XmlReader读取XML时自动解析DTD实体,如何禁用以保留实体?
如何用XmlReader读取XML时保留自定义实体引用
我之前处理XML文档时也遇到过一模一样的问题——XmlReader默认会自动把自定义实体替换成对应文本,要保留&EntityOne;这种原始引用,得调整它的配置参数才行。
核心思路是修改XmlReaderSettings的几个关键属性,让阅读器只解析DTD但不替换自定义实体:
- 设置
DtdProcessing为Parse:让XmlReader能识别文档里的DTD实体定义,不然它会直接忽略实体声明,甚至报错。 - 设置
EntityHandling为EntityHandling.ExpandCharEntities:这个是关键,它会让阅读器只替换&、<这类标准字符实体,而你的自定义实体(比如&EntityOne;)会以单独的实体引用节点被读取,不会被替换成文本。 - 额外加个
XmlResolver = null:避免解析外部实体,既安全又能防止意外的实体替换。
给你贴个可直接用的代码示例:
// 配置XmlReader的参数 var readerSettings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Parse, EntityHandling = EntityHandling.ExpandCharEntities, XmlResolver = null // 禁用外部实体解析,提升安全性 }; // 读取XML文档 using (XmlReader reader = XmlReader.Create("你的XML文件路径或流", readerSettings)) { while (reader.Read()) { // 当遇到实体引用节点时,直接获取实体名称 if (reader.NodeType == XmlNodeType.EntityReference) { Console.WriteLine($"捕获到实体引用:&{reader.Name};"); } // 处理文本节点 else if (reader.NodeType == XmlNodeType.Text) { Console.WriteLine($"文本内容:{reader.Value}"); } // 其他节点类型按需处理 } }
举个例子,你的XML里<string name="r1">&EntityOne; is getting mapped to the string</string>这段内容,用上面的代码读取时,会先读到一个EntityReference节点(名称是EntityOne),然后读到一个文本节点(内容是 is getting mapped to the string),这样你就能自己拼接出保留实体引用的完整内容了。
内容的提问来源于stack exchange,提问作者StephenH
相关产品推荐
相关产品推荐

