C# 如何防止XMLReader删除字符

C# 如何防止XMLReader删除字符,c#,escaping,xmlreader,C#,Escaping,Xmlreader,我想创建一个简单的XMLreader,它将完整的节点(包括子节点)读取为文本: 我希望得到结果: "<text>hall&#xF6;le</text>" “大厅ö;乐” 我怎么能称之为“逃避”。我想将这些片段存储到数据库中,并且确实需要转义。此外,我不想解析和重新创建片段。查看xml头并验证它是否包含以下内容: 对于转义和取消转义,可以使用c函数InnerXml和InnerText: public static string XmlEscape(str

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

我希望得到结果:

"<text>hall&#xF6;le</text>"
“大厅ö;乐”

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

查看xml头并验证它是否包含以下内容:

对于转义和取消转义,可以使用c函数
InnerXml
InnerText

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;
}

我理解您不需要解析和重新创建转义字符的愿望,但我找不到不解析和重新创建转义字符的方法,除非您完全使用它。也许这没那么糟糕吧

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;", "&");
string TXML=@“hallö;le”;
TXML=TXML.Replace(“&”、“&;”);
XmlTextReader r=新的XmlTextReader(新的StringReader(TXML));
r、 Read();r、 Read();
字符串o=r.ReadOuterXml();
o=o。替换(“&;”、“&”);

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

这两种解决方案都直接使用“XmlTextReader”而不是“XmlReader”。它带有“LinePosition”属性,它将我引向第一个解决方案,并以“ReadChars”方法作为第二个解决方案的基础

解决方案(1),通过索引从原始字符串获取数据 问题:

  • 对流输入不起作用
  • 如果xml有多行,则不起作用
代码

string TXML=@“hallö;le3”;
//XmlReader r=XmlReader.Create(新的StringReader(TXML));
XmlTextReader r=新的XmlTextReader(新的StringReader(TXML));
//读取到应检索为“原始”的节点
while(r.Read())
{
if(r.Name.Equals(“rawnode”))
打破
}
//我们从这里开始
int Begin=r.LinePosition;
r、 跳过();
int End=r.LinePosition;
//把它拿出来
字符串输出=TXML.Substring(Begin-2,End-Begin);
解决方案(2),使用“ReadChars”获取数据 问题:

  • 我必须解析并重新创建我想要阅读的标记的“外部”标记
  • 这可能会影响性能
  • 我可能会引入错误
代码:

/。。。再次创建XmlTextReader并读取到rawnode,然后:
//我们从这里开始
int-buflen=15;
char[]buf=新字符[buflen];
StringBuilder sb=新的StringBuilder(“”);
r、 MoveToContent();
//获取原始内部数据
int-cnt;
而((cnt=r.ReadChars(buf,0,buflen))>0)
{

如果(cnt我遇到了类似的问题,我希望在读取xml时保留转义字符,但在5月份调用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()
string TXML=@“hallö;le”;
TXML=TXML.Replace(“&”、“&;”);
XmlTextReader r=新的XmlTextReader(新的StringReader(TXML));
r、 Read();r.Read();
//现在我们到了文本元素
r、 ReadStartElement()
var content=SecurityElement.Escape(r.ReadContentAsString())
r、 ReadEndElement()

您能否更改XML源以转义
&
符号和
?当您将数据插入数据库时,我认为您希望它是正确的数据,而不是转义的数据。这样您就可以搜索它,当您从数据库读回数据时,它将是正确的。您不需要转义当您使用ADO和参数时,将数据插入到数据库中。我是中间的人。我不能更改源。此外,如果我将存储的数据传递回客户端,他希望它再次逃脱。这就是为什么我愿意将它保留原样。但是用相同的代码解析该字符串不会改变结果。此外,感谢您的方法Xml(un)Escape但使用它们意味着读取和重新创建整个内部XML。这正是我尝试使用的方法。是的,也许这是唯一的方法。谢谢你。但显然,从一个非常粗略的解决方案来看,它可能在应用程序性能中可见。我从一个大XML中读取片段,并且必须多次读取和写入源代码.同一个源?只需读入一次并将其存储在变量中,然后您就可以根据需要多次写入。
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;", "&");
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);
// ... 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();
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()