【发布时间】:2021-06-02 11:41:02
【问题描述】:
我想解析可能有也可能没有 DTD 的 XML 文档。如果有 DTD,那么我想用它来扩展实体引用。如果没有 DTD(更严格地说,如果没有 DOCTYPE 声明),我只想忽略 DTD 处理。
当我设置XmlReaderSettings.DtdProcessing=Ignore 时,包含实体引用的文档解析失败,因为该实体被视为未声明。
当我设置 XmlReaderSettings.DtdProcessing=Parse 时,解析没有 DOCTYPE 声明的文档会失败,诊断结果相当模糊:
The empty string '' is not a valid name. (Parameter 'docTypeName')
System.ArgumentException: The empty string '' is not a valid name. (Parameter 'docTypeName')
at System.Xml.DtdParser.InitializeFreeFloatingDtd(String baseUri, String docTypeName, String publicId, String systemId, String internalSubset, IDtdParserAdapter adapter)
at System.Xml.DtdParser.System.Xml.IDtdParser.ParseFreeFloatingDtd(String baseUri, String docTypeName, String publicId, String systemId, String internalSubset, IDtdParserAdapter adapter)
at System.Xml.XmlTextReaderImpl.ParseDtdFromParserContext()
at System.Xml.XmlTextReaderImpl.ProcessDtdFromParserContext(XmlParserContext context)
at System.Xml.XmlTextReaderImpl.FinishInitStream()
at System.Xml.XmlTextReaderImpl..ctor(Stream stream, Byte[] bytes, Int32 byteCount, XmlReaderSettings settings, Uri baseUri, String baseUriStr, XmlParserContext context, Boolean closeInput)
at System.Xml.XmlReaderSettings.CreateReader(Stream input, Uri baseUri, String baseUriString, XmlParserContext inputContext)
at System.Xml.XmlReader.Create(Stream input, XmlReaderSettings settings, XmlParserContext inputContext)
是否有任何设置可以处理这两种情况,还是我需要先查看内容并相应地设置解析器?
我怀疑这可能与 XmlParserContext 有关(鉴于堆栈跟踪上的此功能),但我不知道如何初始化 XmlParserContext,因为我不知道里面有什么提前文件。我提供了一个XmlParserContext,其中没有为docTypeName 提供任何值。
【问题讨论】:
-
如果性能不是问题,如果
Parse失败,您可以尝试Ignore。 -
您是否尝试过不使用 XmlParserContext 参数?
-
我已经深入研究了我设置 DtdProcessing=Parse 的情况,但它仍然没有解析实体引用,所以我还缺少其他东西。
-
@Dialectus 这将是一个可怕的最后手段。偷看输入流可能是一个较小的邪恶,但仍然很可怕。
-
你也可以先试试
Prohibit。它会在解析过程的早期失败,并提供更多有用的文本,如果失败则使用Parse。Prohibit帮你偷看。