gpt4 book ai didi

c# - 如何防止 .NET XML 解析器扩展 XML 中的参数实体?

转载 作者:太空宇宙 更新时间:2023-11-03 13:06:36 25 4
gpt4 key购买 nike

当我尝试解析下面的 xml(使用下面的代码)时,我不断收到 <sgml>&question;&signature;</sgml>

扩展为

<sgml>Why couldn’t I publish my books directly in standard SGML? — William Shakespeare.</sgml>

<sgml></sgml>

因为我正在研究 XML 3 向合并算法,所以我想检索未扩展的 <sgml>&question;&signature;</sgml>

我试过:

  • 正常解析 xml(这导致扩展的 sgml 标记)
  • 从 xml 开头删除 Doctype 这会导致空 sgml 标记)
  • 各种 XmlReader DTD 设置

我有以下 XML 文件:

<!DOCTYPE sgml [
<!ELEMENT sgml ANY>
<!ENTITY std "standard SGML">
<!ENTITY signature " &#x2014; &author;.">
<!ENTITY question "Why couldn&#x2019;t I publish my books directly in &std;?">
<!ENTITY author "William Shakespeare">
]>
<sgml>&question;&signature;</sgml>

这是我尝试过的代码(多次尝试):

using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Reflection;

class Program
{
static void Main(string[] args)
{
string xml = @"C:\src\Apps\Wit\MergingAlgorithmTest\MergingAlgorithmTest\Tests\XMLMerge-DocTypeExpansion\DocTypeExpansion.0.xml";
var xmlSettingsIgnore = new XmlReaderSettings
{
CheckCharacters = false,
DtdProcessing = DtdProcessing.Ignore
};

var xmlSettingsParse = new XmlReaderSettings
{
CheckCharacters = false,
DtdProcessing = DtdProcessing.Parse
};

using (var fs = File.Open(xml, FileMode.Open, FileAccess.Read))
{
using (var xmkReaderIgnore = XmlReader.Create(fs, xmlSettingsIgnore))
{
// Prevents Exception "Reference to undeclared entity 'question'"
PropertyInfo propertyInfo = xmkReaderIgnore.GetType().GetProperty("DisableUndeclaredEntityCheck", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
propertyInfo.SetValue(xmkReaderIgnore, true, null);

var doc = XDocument.Load(xmkReaderIgnore);

Console.WriteLine(doc.Root.ToString()); // outputs <sgml></sgml> not <sgml>&question;&signature;</sgml>
}// using xml ignore

fs.Position = 0;
using (var xmkReaderIgnore = XmlReader.Create(fs, xmlSettingsParse))
{
var doc = XDocument.Load(xmkReaderIgnore);
Console.WriteLine(doc.Root.ToString()); // outputs <sgml>Why couldn't I publish my books directly in standard SGML? - William Shakespeare.</sgml> not <sgml>&question;&signature;</sgml>
}

fs.Position = 0;
string parseXmlString = String.Empty;
using (StreamReader sr = new StreamReader(fs))
{
for (int i = 0; i < 7; ++i) // Skip DocType
sr.ReadLine();

parseXmlString = sr.ReadLine();
}

using (XmlReader xmlReaderSkip = XmlReader.Create(new StringReader(parseXmlString),xmlSettingsParse))
{
// Prevents Exception "Reference to undeclared entity 'question'"
PropertyInfo propertyInfo = xmlReaderSkip.GetType().GetProperty("DisableUndeclaredEntityCheck", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
propertyInfo.SetValue(xmlReaderSkip, true, null);

var doc2 = XDocument.Load(xmlReaderSkip); // Empty sgml tag

}
}//using FileStream
}
}

最佳答案

Linq-to-XML 不支持实体引用的建模——它们会自动扩展为它们的值(source 1source 2)。根本就没有 XObject 的子类为一般实体引用定义。

但是,假设您的 XML 有效(即实体引用存在于 DTD 中,它们在您的示例中就是这样做的),您可以使用 旧的 XML Document Object Model 解析您的 XML 并插入 XmlEntityReference节点到您的 XML DOM 树中,而不是将实体引用扩展为纯文本:

        using (var sr = new StreamReader(xml))
using (var xtr = new XmlTextReader(sr))
{
xtr.EntityHandling = EntityHandling.ExpandCharEntities; // Expands character entities and returns general entities as System.Xml.XmlNodeType.EntityReference
var oldDoc = new XmlDocument();
oldDoc.Load(xtr);
Debug.WriteLine(oldDoc.DocumentElement.OuterXml); // Outputs <sgml>&question;&signature;</sgml>
Debug.Assert(oldDoc.DocumentElement.OuterXml.Contains("&question;")); // Verify that the entity references are still there - no assert
Debug.Assert(oldDoc.DocumentElement.OuterXml.Contains("&signature;")); // Verify that the entity references are still there - no assert
}

ChildNodes每个 XmlEntityReference 都将具有一般实体的文本值。如果一个通用实体引用其他通用实体,就像您的情况一样,相应的内部 XmlEntityReference 将嵌套在外部的 ChildNodes 中。然后,您可以使用旧的 XmlDocument API 比较旧的和新的 XML。

请注意,您还需要使用旧的 XmlTextReader并设置 EntityHandling = EntityHandling.ExpandCharEntities .

关于c# - 如何防止 .NET XML 解析器扩展 XML 中的参数实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30598841/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com