如何防止XMLReader无法转义字符

时间:2012-05-22 14:46:17

标签: c# escaping xmlreader

我想创建一个简单的XMLreader,它将一个完整的节点(包括子节点)作为文本读取:

string TXML = @"<xml><text>hall&#xF6;le</text></xml>";

XmlReader r = XmlReader.Create(new StringReader(TXML));
r.Read(); r.Read();

string o = r.ReadOuterXml();

ReadOuterXml完成了这项工作,但它解除了已经逃过的迹象:

"<text>hallöle</text>"
我希望得到结果:

"<text>hall&#xF6;le</text>"

我怎么能省略'unescaping'。我想将这些片段存储到数据库中,并且需要进行转义。此外,我不想解析并重新创建片段。

4 个答案:

答案 0 :(得分:3)

我有一个类似的问题,我想在从xml读取时保留转义的字符,但在调用ReadOuterXml()的情况下,只保留了一些字符并且至少转换了oane(我头“而不是” )

我的解决方案如下:

string TXML = @"<xml><text>hall&#xF6;le</text></xml>";
TXML = TXML.Replace("&", "&amp;");
XmlTextReader r = new XmlTextReader(new StringReader(TXML));
r.Read(); r.Read();
// now we are at the text element
r.ReadStartElement()
var content = SecurityElement.Escape(r.ReadContentAsString())
r.ReadEndElement()

答案 1 :(得分:2)

我找到了两个解决方案。两者都不是很好,但也许你可以告诉我哪些缺点较少。

两种解决方案都依赖于直接使用'XmlTextReader'而不是'XmlReader'。它带有属性'LinePosition',它引导我进入第一个解决方案,并使用方法'ReadChars'作为第二个解决方案的基础。

解决方案(1),通过索引

从原始字符串中获取数据

问题:

  • 不适用于流输入
  • 如果xml有多行
  • ,则
  • 不起作用

代码

string TXML = @"<xml><data></data><rawnode at=""10 4""><text>hall&#xF6;le</text><z d=""2"">3</z></rawnode><data></data></xml>";

//XmlReader r = XmlReader.Create(new StringReader(TXML));
XmlTextReader r = new XmlTextReader(new StringReader(TXML));

// read to node which shall be retrived "raw"
while ( r.Read() )
{
    if ( r.Name.Equals("rawnode") )
        break;
}

// here we start
int Begin = r.LinePosition;
r.Skip();
int End = r.LinePosition;

// get it out
string output=TXML.Substring(Begin - 2, End - Begin);

解决方案(2),使用'ReadChars'获取数据

问题:

  • 我必须解析并重新创建我想要阅读的标签的“外部”标记。
  • 这可能会降低性能。
  • 我可能会介绍错误。

代码:

// ... again create XmlTextReader and read to rawnode, then:
// here we start
int buflen = 15;
char[] buf = new char[buflen];
StringBuilder sb= new StringBuilder("<",20);

//get start tag and attributes    
string tagname=r.Name;
sb.Append(tagname);
bool hasAttributes = r.MoveToFirstAttribute();
while (hasAttributes)
{
    sb.Append(" " + r.Name + @"=""" + r.Value + @"""");
    hasAttributes = r.MoveToNextAttribute();
}
sb.Append(@">");
r.MoveToContent();

//get raw inner data    
int cnt;
while ((cnt = r.ReadChars(buf, 0, buflen)) > 0)
{
    if ( cnt<buflen )
        buf[cnt]=(char)0;
    sb.Append(buf);
}

//append end tag    
sb.Append("</" + tagname + ">");

// get it out
string output = sb.ToString();

答案 2 :(得分:1)

查看xml标头并验证其中包含以下内容:<?xml version="1.0" encoding="ISO-8859-9"?>

对于转义和转义,您可以使用c#函数InnerXmlInnerText

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

public static string XmlUnescape(string escaped)
{
    XmlDocument doc = new XmlDocument();
    var node = doc.CreateElement("root");
    node.InnerXml = escaped;
    return node.InnerText;
}

答案 3 :(得分:0)

我理解你不需要解析和重新创建转义字符的愿望,但我找不到办法,除非你完全定制它。也许这不是很糟糕?

string TXML = @"<xml><text>hall&#xF6;le</text></xml>";
TXML = TXML.Replace("&", "&amp;");
XmlTextReader r = new XmlTextReader(new StringReader(TXML));
r.Read(); r.Read();

string o = r.ReadOuterXml();
o = o.Replace("&amp;", "&");