问题描述
我看了一下,发现它非常有用。 p>
我想做一个类似的事情:逃避一个要在XML属性中使用的字符串。
字符串可能包含\r\\\
。
XmlWriter类产生类似\r\\\
- >& #xD;& #xA;
我目前正在使用的解决方案包括XmlWriter和一个StringBuilder,而且很丑陋。
任何提示?
Edit1: / strong>
对不起,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\\\
将导致
Bar)Foo\r\\\
Bar
我使用.NET Reflector来了解XmlTextWriter如何转义属性。它使用内部的XmlTextEncoder类...
我的方法我目前是usig这样的信息:
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 = \。
return sb.ToString();
}
它的丑陋可能很慢,但它的工作: XmlEscapeAttribute(Foo\r\\\
将导致
Bar)Foo& #xD;& #xA; Bar
/ p>
Edit2:
SecurityElement.Escape (未逸出);
不起作用。
Edit3(final):
使用Lars的所有非常有用的注释,我的最终实现如下所示:
注意: .Replace(\r,& #xD;)替换(\\\
不需要有效的XMl。这只是一个美容方法!
& #xA;);
public static string XmlEscapeAttribute(string unescaped)
{
XmlDocument doc = new XmlDocument();
XmlAttribute attr = doc.CreateAttribute(attr);
attr.InnerText = unescaped;
//替换是*不*必填!
return attr.InnerXml.Replace(\r,& #xD;)。Replace(\\\
,& #xA;);
}
事实证明,这是有效的XML,将被任何标准兼容XMl-parser:
< response message =谢谢,
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属性。
我没有环境来测试这个,但是我很好奇地知道如果它有效。
更新:或者更简单的说,使用 ,如您所链接的问题的另一个答案所建议的。这将排除引号,因此适用于属性文本。
更新2:请注意回车和换行不需要在属性值中转义,以使XML格式正确。如果您希望他们因为其他原因被转义,可以使用String.replace()来执行,例如
SecurityElement.Escape (未转义).Replace(\r,& #xD;)。Replace(\\\
,& #xA;);
或
return node.InnerXml.Replace(\r,& #xD;)。Replace(\\\
,& #xA;);
I had a look at string escape into XML and found it very useful.
I would like to do a similar thing: Escape a string to be used in an XML-Attribute.
The string may contain \r\n.The XmlWriter class produces something like \r\n -> 

The solution I'm currently using includes the XmlWriter and a StringBuilder and is rather ugly.
Any hints?
Edit1:
Sorry to disappoint LarsH, buy my first approach was
public static string XmlEscapeAttribute(string unescaped)
{
XmlDocument doc = new XmlDocument();
XmlAttribute attr= doc.CreateAttribute("attr");
attr.InnerText = unescaped;
return attr.InnerXml;
}
It does not work. XmlEscapeAttribute("Foo\r\nBar")
will result in "Foo\r\nBar"
I used the .NET Reflector, to find out how the XmlTextWriter escapes Attributes. It uses the XmlTextEncoder class which is internal...
My method I'm currently usig lokks like this:
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();
}
It's ugly and probably slow, but it does work: XmlEscapeAttribute("Foo\r\nBar")
will result in "Foo
Bar"
Edit2:
SecurityElement.Escape(unescaped);
does not work either.
Edit3 (final):
Using all the very useful comments from Lars, my final implementation looks like this:
Note: the .Replace("\r", "
").Replace("\n", "
");
is not required for valid XMl. It is a cosmetic measure only!
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", "
");
}
As it turns out this is valid XML and will be parsed by any standard compliant XMl-parser:
<response message="Thank you,
LarsH!" />
Modifying the solution you referenced, how about
public static string XmlEscape(string unescaped)
{
XmlDocument doc = new XmlDocument();
var node = doc.CreateAttribute("foo");
node.InnerText = unescaped;
return node.InnerXml;
}
All I did was change CreateElement() to CreateAttribute().The attribute node type does have InnerText and InnerXml properties.
I don't have the environment to test this in, but I'd be curious to know if it works.
Update: Or more simply, use SecurityElement.Escape() as suggested in another answer to the question you linked to. This will escape quotation marks, so it's suitable for using for attribute text.
Update 2: Please note that carriage returns and line feeds do not need to be escaped in an attribute value, in order for the XML to be well-formed. If you want them to be escaped for other reasons, you can do it using String.replace(), e.g.
SecurityElement.Escape(unescaped).Replace("\r", "
").Replace("\n", "
");
or
return node.InnerXml.Replace("\r", "
").Replace("\n", "
");
这篇关于字符串转义为XML-Attribute的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!