2

我想创建一个简单的 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>"

我怎么能省略那个“逃避”。我想将这些片段存储到数据库中,并且确实需要转义。此外,我不想解析和重新创建片段。

4

4 回答 4

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()
于 2012-11-14T13:11:31.433 回答
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();
于 2012-05-23T14:42:46.980 回答
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;
}
于 2012-05-22T14:53:17.790 回答
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;", "&");
于 2012-05-22T15:25:35.600 回答