此XML文档中禁止DTD

时间:2011-10-20 18:26:32

标签: c# xml

你喜欢谜题解决吗?这是一个很大的问题!

首先,我对解决方案进行了大量研究,但是,我的情况仍然很复杂。

好吧,我有一个在复杂的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 下面我有我的问题,元素dsig:Signature

要验证LoteRps我有我的XSD文件(如上所述),但要验证 dsig:Signature

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

ProcessLoteRps(XmlDocument loteRpsXml);

当我收到Xml(包含元素LoteRps和Signature)时,我需要验证XML,以验证LoteRps和Signature是否在正确的sctruture中。我在验证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)。
  3. 如果我没有为Signature添加架构,我会收到以下错误:

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

    好的,那么,理论上我必须添加Signature模式进行验证,如下所示:

    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.
    

    好吧,在谷歌研究,我找到了很多链接:

    Problem validation a XML file with a local DTD file in C#

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

    我尝试了很多东西,但仍然收到错误..

    然后我试图发明:

    public static List 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

    拜托,我需要你的帮助。

    祝你好运, 丹

1 个答案:

答案 0 :(得分:2)

每次程序运行时都不应从服务器下载架构。您应该下载一次并将其保存在硬盘上。

我认为这也会解决“协议违规”错误。