.NET XmlDocument LoadXML和实体
将XML加载到XmlDocument中时,即
XmlDocument document = new XmlDocument(); document.LoadXml(xmlData);
有什么方法可以阻止替换实体的过程?我遇到了一个奇怪的问题,我在xml中将TM符号(存储为实体#8482)转换为TM字符。就我而言,这应该不会发生,因为XML文档的编码为ISO-8859-1(没有TM符号)
谢谢
解决方案
我承认事情与XML文档和编码有些混淆,但是我希望如果我们仍然使用ISO-8859-1,但是如果我们使用UTF-8保存,那么在再次保存时将其设置适当。 ,则不需要。在某些方面,从逻辑上说,文档实际上包含符号,而不是实体引用,后者只是一个编码问题。 (我在这里大声思考,请不要以此为权威信息。)
加载文档后我们将如何处理?
我相信如果我们将实体内容包含在CDATA部分中,则应将其全部保留下来,例如
<root> <testnode> <![CDATA[some text ™]]> </testnode> </root>
你在写什么呢?一个TextWriter?流?什么?
以下内容保留了实体(嗯,它用等效的十六进制替换了它),但是如果我们使用StringWriter进行相同操作,它将检测到unicode并改为使用它:
XmlDocument doc = new XmlDocument(); doc.LoadXml(@"<xml>™</xml>"); using (MemoryStream ms = new MemoryStream()) { XmlWriterSettings settings = new XmlWriterSettings(); settings.Encoding = Encoding.GetEncoding("ISO-8859-1"); XmlWriter xw = XmlWriter.Create(ms, settings); doc.Save(xw); xw.Close(); Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray())); }
输出:
<?xml version="1.0" encoding="iso-8859-1"?><xml>™</xml>
实体引用不是特定于编码的。根据W3C XML 1.0建议:
If the character reference begins with "&#x", the digits and letters up to the terminating ; provide a hexadecimal representation of the character's code point in ISO/IEC 10646.
这是对XML工具集的标准误解。带有"&#x"的整个业务是一种旨在处理字符编码的语法功能。XmlDocument不是字符流,它没有字符编码问题,而是包含XML类型数据的抽象模型。包括DOM和InfoSet这样的词,我不确定究竟是正确的。
此模型中不存在"&#x" gubbins,因为整个问题都无关紧要,当我们将信息集以某种特定编码转换回字符流时,它将在适当时返回。
这种误解已经很普遍,以至于作为一系列类似怪癖的一部分被纳入学术文献。在此位置查看" Xml发烧":http://doi.acm.org/10.1145/1364782.1364795
&#xxxx;实体被认为是它们代表的字符。阅读时所有XML都将转换为unicode,并且将删除任何此类实体,以支持它们表示的unicode字符。这包括在unicode源中发生的任何事件,例如传递给LoadXML的字符串。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
类似地,在写入时,无法由正在写入的流表示的任何字符都将转换为&#xxxx;。实体。试图保护它们毫无意义。
我通过编写一个HtmlEncode函数解决了我的问题,该函数实际上将所有字符替换掉后才将它们吐出到网页上(而不是依赖于有点破损的HtmlEncode().NET函数,该函数似乎仅对HtmlEncode()必需的字符)
标题数量不匹配