繁体   English   中英

XmlSchemaSet DTD处理

[英]XmlSchemaSet DTD Processing

我正在尝试针对xsd验证xml。

 XmlSchemaSet schema = new XmlSchemaSet();
 schema.Add("", "http://abc.cba/OrderRequest"); <-- error

并得到以下错误

  For security reasons DTD is prohibited in this XML document. 
  To enable DTD processing set the DtdProcessing property on XmlReaderSettings to 
  Parse and pass the settings into XmlReader.Create method

首先,没有任何XmlReader.Create方法,因此想知道为什么在该行上出现这种错误。

其次,我用google搜索并发现以下代码,因为不知道在哪里将readersettings添加到架构中。

 XmlReaderSettings readerSettings = new XmlReaderSettings();
 readerSettings.ValidationType = ValidationType.DTD;
 readerSettings.DtdProcessing = DtdProcessing.Parse;

我最初以为可以在读取Xml时抛出此错误。 但是,看着您的问题,我进行了一些测试,可以看到尝试添加DTD文件会引发此异常。

由于XSD也是Xml文件,因此在内部它是“读取Xml”而引发此异常。

仔细观察,我得到以下StackTrace

Unhandled Exception: System.Xml.XmlException: For security reasons DTD is prohibited in this XML document. To enable DTD processing set the DtdProcessing property on XmlReaderSettings to Parse and pass the settings into XmlReader.Create method.
   at System.Xml.XmlTextReaderImpl.Throw(Exception e)
   at System.Xml.XmlTextReaderImpl.ParseDoctypeDecl()
   at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
   at System.Xml.Schema.Parser.StartParsing(XmlReader reader, String targetNamespace)
   at System.Xml.Schema.Parser.Parse(XmlReader reader, String targetNamespace)
   at System.Xml.Schema.XmlSchemaSet.ParseSchema(String targetNamespace, XmlReader reader)
   at System.Xml.Schema.XmlSchemaSet.Add(String targetNamespace, String schemaUri)

然后,查看.Net框架源代码,以下引发异常

资源

    // Parses DOCTYPE declaration
    private bool ParseDoctypeDecl() {
        if ( dtdProcessing == DtdProcessing.Prohibit ) {
            ThrowWithoutLineInfo( v1Compat ? Res.Xml_DtdIsProhibited : Res.Xml_DtdIsProhibitedEx );
        }

仔细观察, XmlSchemaSet类构造一个具有此属性集的XmlReaderSettings

的XmlSchemaSet

readerSettings = new XmlReaderSettings();
readerSettings.DtdProcessing = DtdProcessing.Prohibit;

现在,这说明了错误的原因。

我找不到公开的方法来超越此属性。 如果您确实要更改此设置,则可以使用反射。

        XmlSchemaSet schema = new XmlSchemaSet();

        var value = schema.GetType().GetProperty("ReaderSettings", BindingFlags.GetProperty | BindingFlags.NonPublic | BindingFlags.Instance).GetValue(schema) as XmlReaderSettings;

        value.DtdProcessing = DtdProcessing.Parse;

请谨慎使用以上代码,因为在.Net Framework的将来版本中可以更改内部属性/字段。

基于此,我认为更正确的选择是为您的架构寻找XSD(而不是DTD)。

XSD是可取的。

我发现了一种不使用反射的方法,如此处所述: https : //social.msdn.microsoft.com/Forums/expression/en-US/c88ef0b0-39a8-413e-8e35-deb95fb57e58/validate-xsd-against-w3- xmlschemaxsd?论坛= xmlandnetfx

解决方案是使用XmlSchemaSet并使用您自己的XmlReader添加架构。

XmlSchemaSet set = new XmlSchemaSet();
using (XmlReader xr = XmlReader.Create(
    new XmlTextReader("https://www.w3.org/2001/XMLSchema.xsd"),
    new XmlReaderSettings() { DtdProcessing = DtdProcessing.Ignore }))
{
    set.Add(null, xr);
}
set.Compile();

// Set the validation settings.
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add(set);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM