Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用System.Xml.XmlReader,解析DTD(如果存在),但不';如果缺席,就不要失败_C#_Xml_Dtd - Fatal编程技术网

C# 使用System.Xml.XmlReader,解析DTD(如果存在),但不';如果缺席,就不要失败

C# 使用System.Xml.XmlReader,解析DTD(如果存在),但不';如果缺席,就不要失败,c#,xml,dtd,C#,Xml,Dtd,我想解析可能有也可能没有DTD的XML文档。如果有DTD,那么我想用它来扩展实体引用。如果没有DTD(更严格地说,如果没有DOCTYPE声明),我只想忽略DTD处理 当我设置XmlReaderSettings.DtdProcessing=Ignore时,解析包含实体引用的文档失败,因为该实体被视为未声明 当我设置XmlReaderSettings.DtdProcessing=Parse时,没有DOCTYPE声明的文档解析失败,诊断相当模糊: The empty string '' is not

我想解析可能有也可能没有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
提供任何值。好的,我想我已经解决了这个问题。我走了一些错误的路线,一些是我自己做的,一些是由糟糕的文档引发的

我现在创建一个类似这样的解析器,不管是否有DOCTYPE声明:

XmlReaderSettings settings = new XmlReaderSettings();
settings.ProhibitDtd = false;
settings.MaxCharactersFromEntities = 1024;
settings.XmlResolver = new MyXmlResolver(new Uri(source.getSystemId()));
xmlReader = XmlReader.Create(inputStream, settings);
没有必要使用
XmlParserContext
对象,它似乎只是挡住了路(我仍然不知道它到底做了什么)

我没有找到同时向解析器提供输入流和基本URI的方法,因此我使用自己的XmlResolver,它知道基本URI,并使用它代替提供给XmlResolver的
ResolveUri
方法的方法

我观察到的故障原因如下:

(a)
System.ArgumentException
是由于我试图提供一个
XmlParserContext
而导致的,当我切换到一个不使用它的构造函数时,它就消失了。(谢谢,@jdweng)


(b) “entity not declared”错误是由于解析DTD系统id的无声故障造成的,这反过来又是由于我没有找到任何成功的方法向解析器提供基本URI(我尝试使用
XmlParserContext
来实现这一点被证明是错误的).

如果性能不是一个问题,您可以尝试
忽略
如果
解析
失败。您是否在没有XmlParserContext参数的情况下进行了尝试?我已经深入讨论了设置DtdProcessing=Parse的情况,但它仍然没有解析实体引用,所以我还遗漏了一些东西,那将是一个可怕的最后手段。偷看输入流可能不是什么坏事,但仍然很可怕。您也可以先尝试
禁止
。它将在解析过程的早期失败,并生成更多有用的文本,如果失败,则使用
Parse
<代码>禁止
为您进行窥视。