首先,我对解决方案进行了大量研究,但是,我的情况仍然很复杂。
好吧,我有一个在复杂的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个模式:
如果我没有为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
拜托,我需要你的帮助。
祝你好运, 丹
答案 0 :(得分:2)
每次程序运行时都不应从服务器下载架构。您应该下载一次并将其保存在硬盘上。
我认为这也会解决“协议违规”错误。