此XML文档禁止使用DTD

本文关键字:DTD 禁止 XML 文档 | 更新日期: 2023-09-27 18:11:45

你喜欢谜题吗?这是一个大问题!

首先,为了解决这个问题,我做了很多研究,但是,我的情况仍然很复杂。

嗯,我有一个在复杂的XSD文件中验证的XML,但是,在该XML中,我还有另一个用于数字签名的复杂类型(xmlsignature)。

我的XSD是:

  <xsd:element name="EnviarLoteRpsEnvio">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="LoteRps" type="tcLoteRps"/>
        <xsd:element ref="dsig:Signature" minOccurs="0" maxOccurs="1"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>

LoteRps(想象一个像TPerson这样的类)是一个复杂的类型,在LoteRps下面我有我的问题,元素设计:签名

为了验证LoteRps,我有我的XSD文件(如上所述),但是,为了验证设计:签名

我在做什么?答:我正在做一个接受XML作为参数的web服务。例如:

ProcessLoteRps(XmlDocument loteRpsXml);

当我收到Xml(包含LoteRps和Signature元素)时,我需要验证Xml,以验证LoteRps和Signature是否在正确的结构中。在验证LoteRps结构时没有问题,因为我可以添加模式,但是,当我为Signature添加模式时,就会出现错误。验证代码:

//function that returns the erros of the XML structure - if is wrong - in a list of string    
public static List<string> ValidaXMLComXSD(XmlDocument xmlTemp)
            {
                List <string> lista_erros = new List<string>();
                try
                {
                    // add the schemas...
                    xmlTemp.Schemas.Add("http://www.abrasf.org.br/ABRASF/arquivos/nfse.xsd", "Models'XSD'NFSE.xsd");
                    // HEY BRO, THE PROBLEM OCCURS HERE
                    xmlTemp.Schemas.Add("http://www.w3.org/2000/09/xmldsig#", HttpContext.Current.Server.MapPath("~/") + @"Models'XSD'xmldsig-core-schema20020212.xsd");
                }
                catch (Exception e)
                {
                    throw new Exception("Erro ao validar o XML: " + e.Message);
                }
            }
如我们所见,我添加了2个模式:
  1. 验证RPS(通过XSD);
  2. 验证签名(通过DTD)。

如果我没有为Signature添加模式,我得到以下错误:

The 'http://www.w3.org/2000/09/xmldsig#:Signature' element is not declared.

好的,那么,理论上我必须添加签名模式来验证,如下所示:

xmlTemp.Schemas.Add("http://www.w3.org/2000/09/xmldsig#", HttpContext.Current.Server.MapPath("~/") + @"Models'XSD'xmldsig-core-schema20020212.xsd");

但是,当我添加那个模式时,我得到另一个(已知的)错误:

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

嗯,在谷歌上搜索,我发现了很多链接:

c#中使用本地DTD文件验证XML文件的问题

http://www.eggheadcafe.com/microsoft/Csharp/33292915/xml-prohibitdtd-error.aspx

我试了很多东西,但是,仍然得到错误…

然后我试着发明:

公共静态列表ValidaXMLComXSD(XmlDocument xmlTemp){

    List <string> lista_erros = new List<string>();
    try
    {
        #region Test
        XmlErrors xmlErros = new XmlErrors();
        XmlReaderSettings xsdSettings = new XmlReaderSettings();
        xsdSettings.ValidationType = ValidationType.Schema;
        xsdSettings.ValidationEventHandler += new ValidationEventHandler(xmlErros.XmlErrorsHandler);

        XmlReaderSettings dtdSettings = new XmlReaderSettings();
        dtdSettings.ValidationType = ValidationType.DTD;
        dtdSettings.ProhibitDtd = false;
        dtdSettings.ValidationEventHandler += new ValidationEventHandler(xmlErros.XmlErrorsHandler);

        xmlTemp.Schemas.Add(null, XmlReader.Create(NFSE_XSD_PATH, xsdSettings));
        // The error occurs below
        xmlTemp.Schemas.Add(null, XmlReader.Create(NFSE_XSD_SIG_PATH, dtdSettings));

出现一个新的错误:

An error has occurred while opening external DTD 'http://www.w3.org/2001/XMLSchema.dtd': The server committed a protocol violation. Section=ResponseStatusLine

然后,它打断了我的腿…

我不知道该怎么办…: s

我需要你的帮助。

最诚挚的问候,丹

此XML文档禁止使用DTD

您不应该在每次程序运行时都从服务器下载模式。你应该下载一次并保存在你的硬盘上。

我想这也会处理" protocol violation "错误