Sim*_*aus 9 c# xml stringbuilder xmlwriter escaping
我看了一下XML转义的字符串,发现它非常有用.
我想做类似的事情:转义要在XML-Attribute中使用的字符串.
该字符串可能包含\ r \n.XmlWriter类产生类似\ r \n - >
我目前使用的解决方案包括XmlWriter和StringBuilder,而且非常难看.
任何提示?
编辑1:
抱歉让LarsH失望,买我的第一个方法是
public static string XmlEscapeAttribute(string unescaped)
{
XmlDocument doc = new XmlDocument();
XmlAttribute attr= doc.CreateAttribute("attr");
attr.InnerText = unescaped;
return attr.InnerXml;
}
Run Code Online (Sandbox Code Playgroud)
这是行不通的.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();
}
Run Code Online (Sandbox Code Playgroud)
它很丑陋,可能很慢,但确实有效:XmlEscapeAttribute("Foo\r\nBar")
会导致"Foo
Bar"
EDIT2:
SecurityElement.Escape(unescaped);
Run Code Online (Sandbox Code Playgroud)
也不起作用.
Edit3(最后):
使用Lars的所有非常有用的注释,我的最终实现如下所示:
注意:.Replace("\r", "
").Replace("\n", "
");
有效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", "
").Replace("\n", "
");
}
Run Code Online (Sandbox Code Playgroud)
事实证明这是有效的XML,并且将由任何符合标准的XMl-parser解析:
<response message="Thank you,
LarsH!" />
Run Code Online (Sandbox Code Playgroud)
修改你引用的解决方案,怎么样
public static string XmlEscape(string unescaped)
{
XmlDocument doc = new XmlDocument();
var node = doc.CreateAttribute("foo");
node.InnerText = unescaped;
return node.InnerXml;
}
Run Code Online (Sandbox Code Playgroud)
我所做的只是将CreateElement()更改为CreateAttribute().属性节点类型确实具有InnerText和InnerXml属性.
我没有环境来测试它,但我很想知道它是否有效.
更新:或者更简单地,使用SecurityElement.Escape(),如您链接到的问题的另一个答案中所建议的那样.这将转义引号,因此适合用于属性文本.
更新2:请注意,不需要在属性值中转义回车符和换行符,以使XML格式正确.如果由于其他原因希望对它们进行转义,可以使用String.replace()进行转义,例如
SecurityElement.Escape(unescaped).Replace("\r", "
").Replace("\n", "
");
Run Code Online (Sandbox Code Playgroud)
要么
return node.InnerXml.Replace("\r", "
").Replace("\n", "
");
Run Code Online (Sandbox Code Playgroud)