字符串转义为 XML 属性

2024-03-30

我看了一下字符串转义为 XML https://stackoverflow.com/questions/1132494/string-escape-into-xml并发现它非常有用。

我想做类似的事情:转义要在 XML 属性中使用的字符串。

该字符串可能包含 \r\n。 XmlWriter 类生成类似 \r\n -> 的内容。

我当前使用的解决方案包括 XmlWriter 和 StringBuilder,而且相当难看。

有什么提示吗?

Edit1:
抱歉让 LarsH 失望了,购买我的第一个方法是

public static string XmlEscapeAttribute(string unescaped)
{
    XmlDocument doc = new XmlDocument();
    XmlAttribute attr= doc.CreateAttribute("attr");
    attr.InnerText = unescaped;
    return attr.InnerXml;
}

这是行不通的。XmlEscapeAttribute("Foo\r\nBar")将导致"Foo\r\nBar"

我使用 .NET Reflector 来了解 XmlTextWriter 如何转义属性。它使用内部的 XmlTextEncoder 类...

我目前使用的方法如下所示:

public static string XmlEscapeAttribute(string unescaped)
{
    if (String.IsNullOrEmpty(unescaped)) return unescaped;

    XmlWriterSettings settings = new XmlWriterSettings();
    settings.OmitXmlDeclaration = true;
    StringBuilder sb = new StringBuilder();
    XmlWriter writer = XmlWriter.Create(sb, settings);

    writer.WriteStartElement("a");
    writer.WriteAttributeString("a", unescaped);
    writer.WriteEndElement();
    writer.Flush();
    sb.Length -= "\" />".Length;
    sb.Remove(0, "<a a=\"".Length);

    return sb.ToString();
}

它很丑陋而且可能很慢,但它确实有效:XmlEscapeAttribute("Foo\r\nBar")将导致"Foo&#xD;&#xA;Bar"

Edit2:

SecurityElement.Escape(unescaped);

也不行。

编辑3(最终):

使用 Lars 的所有非常有用的评论,我的最终实现如下所示:

Note: the .Replace("\r", "&#xD;").Replace("\n", "&#xA;");有效的 XMl 不需要。这只是一个美容措施!

    public static string XmlEscapeAttribute(string unescaped)
    {

        XmlDocument doc = new XmlDocument();
        XmlAttribute attr= doc.CreateAttribute("attr");
        attr.InnerText = unescaped;
        // The Replace is *not* required!
        return attr.InnerXml.Replace("\r", "&#xD;").Replace("\n", "&#xA;");
    }

事实证明这是有效的 XML,并且将由任何符合标准的 XMl 解析器进行解析:

<response message="Thank you,
LarsH!" />

修改你引用的解决方案,怎么样

public static string XmlEscape(string unescaped)
{
    XmlDocument doc = new XmlDocument();
    var node = doc.CreateAttribute("foo");
    node.InnerText = unescaped;
    return node.InnerXml;
}

我所做的只是将 CreateElement() 更改为 CreateAttribute()。 属性节点类型确实具有 InnerText 和 InnerXml 属性。

我没有测试这个的环境,但我很想知道它是否有效。

更新:或者更简单地说,使用SecurityElement.Escape() http://msdn.microsoft.com/en-us/library/system.security.securityelement.escape%28VS.80%29.aspx正如您链接到的问题的另一个答案中所建议的。这将转义引号,因此适合用于属性文本。

更新2:请注意回车和换行不需要逃避属性值中,以便 XML 格式正确。如果您希望出于其他原因转义它们,可以使用 String.replace() 来完成,例如

SecurityElement.Escape(unescaped).Replace("\r", "&#xD;").Replace("\n", "&#xA;");

or

return node.InnerXml.Replace("\r", "&#xD;").Replace("\n", "&#xA;");
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

字符串转义为 XML 属性 的相关文章

随机推荐