首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >XmlSchemaSet DTD处理

XmlSchemaSet DTD处理
EN

Stack Overflow用户
提问于 2017-08-14 06:19:10
回答 2查看 2.3K关注 0票数 2

我正在尝试根据xsd验证xml。

代码语言:javascript
复制
 XmlSchemaSet schema = new XmlSchemaSet();
 schema.Add("", "http://abc.cba/OrderRequest"); <-- error

并得到以下错误

代码语言:javascript
复制
  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方法,所以我想知道为什么这一行会出现这种错误。

其次,我在谷歌上搜索并找到了下面的代码,因为我不知道在哪里将readersettings添加到模式中。

代码语言:javascript
复制
 XmlReaderSettings readerSettings = new XmlReaderSettings();
 readerSettings.ValidationType = ValidationType.DTD;
 readerSettings.DtdProcessing = DtdProcessing.Parse;
EN

回答 2

Stack Overflow用户

发布于 2018-06-13 16:46:05

我找到了一种不使用反射的方法,如下所示:https://social.msdn.microsoft.com/Forums/expression/en-US/c88ef0b0-39a8-413e-8e35-deb95fb57e58/validate-xsd-against-w3-xmlschemaxsd?forum=xmlandnetfx

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

代码语言:javascript
复制
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);
票数 3
EN

Stack Overflow用户

发布于 2017-08-21 02:55:56

我最初认为这个错误可以在reading the Xml时抛出。但是,看看你的问题,我做了一些测试,可以看到尝试添加一个DTD文件会抛出这个异常。

因为XSD也是一个Xml文件,所以在内部是“读取Xml”抛出了这个异常。

看得更近一些,我得到以下StackTrace

代码语言:javascript
复制
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框架源代码,下面抛出异常

Source

代码语言:javascript
复制
    // Parses DOCTYPE declaration
    private bool ParseDoctypeDecl() {
        if ( dtdProcessing == DtdProcessing.Prohibit ) {
            ThrowWithoutLineInfo( v1Compat ? Res.Xml_DtdIsProhibited : Res.Xml_DtdIsProhibitedEx );
        }

更仔细地看,XmlSchemaSet类构造了一个设置了此属性的XmlReaderSettings

XmlSchemaSet

代码语言:javascript
复制
readerSettings = new XmlReaderSettings();
readerSettings.DtdProcessing = DtdProcessing.Prohibit;

现在,这解释了错误的原因。

我找不到一种公共的方法来覆盖这个属性。如果你真的想改变这一点,你可以使用反射。

代码语言:javascript
复制
        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框架的未来版本中更改。

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

XSD是more的首选。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45665387

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档