XML签名元素未声明。

9
我使用Visual Studio XML工具创建了XSD文件。我使用以下的C#代码来验证XML文件,但出现了以下错误:

错误:

元素未声明 'http://www.w3.org/2000/09/xmldsig#:Signature'。

我的问题是如何解决此错误?因为在编辑模式下,XML文件是100%有效的。

谢谢!

C#代码:

  private void buttonValidateXML_Click(object sender, EventArgs e)
        {
            try
            {            
                bool result = IsValidXml2(textBoxSignedXML.Text, textBoxXSDFile.Text, "");
                rtbValidationResult.Text = result.ToString();
            }
            catch (Exception ex)
            {
                rtbValidationResult.Text = ex.Message;
            }
        }

public static bool IsValidXml2(string xmlFilePath, string xsdFilePath, string namespaceName)
        {
            var xdoc = XDocument.Load(xmlFilePath);
            var schemas = new XmlSchemaSet();
            schemas.Add(namespaceName, xsdFilePath);

            bool result = true;
            xdoc.Validate(schemas, (sender, e) =>
            {
                result = false;
            });

            return result;
        }

XML

<?xml version="1.0" encoding="utf-8"?>
<Envelope version="1">
  <Deposit>
    <ClientId>1234567890123</ClientId>
    <Account>0045678</Account>
    <Currency>USD</Currency>
    <Total>5000.00</Total>
    <SignedDate>2016-02-15</SignedDate>     
    <Cheques>
      <Cheque>
        <Images>
          <Front>
            SUkqAAgAAAAPAP4ABAABAAAAAAAAAAABBAABAAAAfQUAAAEBBAABAAAAWgIAAAIBAwABAAAAAQAA
            AAMBAwABAAAABAAAAAYBAwABAAAAAAAAAA4BAgAhAAAA0AAAABEBBAABAAAAAAIAABIBAwABAAAA
            AQAAABUBAwABAAAAAQAAABYBBAABAAAAWgIAABcBBAABAAAAvi8AABoBBQABAAAAAAEAABsBBQAB
            EdF0fRG0R0YRdH2R2XzaI6OxRQAQAQA=
          </Front>
          <Back>
            SUkqAAgAAAAOAP4ABAABAAAAAAAAAAABBAABAAAAgQUAAAEBBAABAAAAVAIAAAIBAwABAAAAAQAA
            AAMBAwABAAAABAAAAAYBAwABAAAAAAAAABEBBAABAAAAAAEAABIBAwABAAAAAQAAABUBAwABAAAA
            AQAAABYBBAABAAAAVAIAABcBBAABAAAAcggAABoBBQABAAAAwAAAABsBBQABAAAA0AAAACgBAwAB
            AAAAAgAAAAAAAAAAAAAAAAAAAAAAyAAAAAEAAAAAAAAAAAAAAMgAAAABAAAAAAAAAAAAAAAAAAAA
            AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//LZCdO1f7iRrKXTqt//pePx///9lNoL487Ajh
            jFyzUrtwg+6gg9VmvCIWA42XMwziSUEEw7GoIcSUWZ3Y0oKmGR3LToGVC2LhkK6H4sorQNRUMLjH
            LTGzlpv3RFCcH4NLB9hvLTmD8tMgOsG+WVaR5AweTcEWMMfaDQxDIx5NwVQx8OMPeGFHLSUlLcSS
            1JtNV/9/rrffuO+h9bx////kfvABABAA
          </Back>
        </Images>
        <MicrCodeCmc>123456789012345678901234567890</MicrCodeCmc>
        <Amount>465.22</Amount>
        <PaymentDate>2016-02-15</PaymentDate>
        <EmissionDate>2016-02-15</EmissionDate>
      </Cheque>
      <Cheque>
        <Images>
          <Front>
            SUkqAAgAAAAPAP4ABAABAAAAAAAAAAABBAABAAAAfQUAAAEBBAABAAAAWgIAAAIBAwABAAAAAQAA
            AAMBAwABAAAABAAAAAYBAwABAAAAAAAAAA4BAgAhAAAA0AAAABEBBAABAAAAAAIAABIBAwABAAAA
            AQAAABUBAwABAAAAAQAAABYBBAABAAAAWgIAABcBBAABAAAAvi8AABoBBQABAAAAAAEAABsBBQAB
            EdF0fRG0R0YRdH2R2XzaI6OxRQAQAQA=
          </Front>
          <Back>
            SUkqAAgAAAAOAP4ABAABAAAAAAAAAAABBAABAAAAgQUAAAEBBAABAAAAVAIAAAIBAwABAAAAAQAA
            AAMBAwABAAAABAAAAAYBAwABAAAAAAAAABEBBAABAAAAAAEAABIBAwABAAAAAQAAABUBAwABAAAA
            AQAAABYBBAABAAAAVAIAABcBBAABAAAAcggAABoBBQABAAAAwAAAABsBBQABAAAA0AAAACgBAwAB
            AAAAAgAAAAAAAAAAAAAAAAAAAAAAyAAAAAEAAAAAAAAAAAAAAMgAAAABAAAAAAAAAAAAAAAAAAAA
            AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//LZCdO1f7iRrKXTqt//pePx///9lNoL487Ajh
            jFyzUrtwg+6gg9VmvCIWA42XMwziSUEEw7GoIcSUWZ3Y0oKmGR3LToGVC2LhkK6H4sorQNRUMLjH
            LTGzlpv3RFCcH4NLB9hvLTmD8tMgOsG+WVaR5AweTcEWMMfaDQxDIx5NwVQx8OMPeGFHLSUlLcSS
            1JtNV/9/rrffuO+h9bx////kfvABABAA
          </Back>
        </Images>
        <MicrCodeCmc>123456789012345678901234567890</MicrCodeCmc>
        <Amount>99999999999</Amount>
        <PaymentDate>2016-02-15</PaymentDate>
        <EmissionDate>2016-02-15</EmissionDate>
      </Cheque>
    </Cheques>
  </Deposit>   
  <Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
    <SignedInfo>
      <CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
      <SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
      <Reference URI="">
        <Transforms>
          <Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
        </Transforms>
        <DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
        <DigestValue>TVO2Gssf5TUdXFYG/PrHDyqYFqs=</DigestValue>
      </Reference>
    </SignedInfo>
    <SignatureValue>KwQInN03ywa0u0t4HedxgE1fOU7XYLQScKuQ6vdYoIZME5Hm5jpFeX2ORA2U+BO7JNjmFilTW05VntS3k98YCZhNXH9Iw/YEC1nw4JJLzygYbbCftkiY5v5+b494mQPryCtscwTtbziW6QilILSFDGmco2JopRfVe+qfdN/JyB1HXhUfApyNEsw/cJLj6aaz5ivN1sLFgAlikbwCNpF+mRnZY5u7/S8uT8WhEyK32EcatdjzKbP0PwnIlumhOpUMerWeLZ7neuJq6R/IuFgZ1Y5U6ppyuOjhtiHp4glC/uNUS/y7jMzG29thWBkEtSE9AcEt2IZ0HOEZE3kdFXufjA==</SignatureValue>
  </Signature>
</Envelope>

XSD

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:tns="http://example.com/ct-required"
           xmlns:xmime="http://www.w3.org/2005/05/xmlmime" >

  <xs:import namespace="http://www.w3.org/2005/05/xmlmime"
            schemaLocation="http://www.w3.org/2005/05/xmlmime"/>

    <xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="xmldsig-core-schema.xsd"/>

  <xs:simpleType name="PNGPictureType"
          xmime:expectedContentTypes="image/png">
    <xs:restriction base="xs:base64Binary"/>
  </xs:simpleType>

  <xs:simpleType name="Money">
    <xs:restriction base="xs:decimal">
      <xs:totalDigits value="13" />
      <xs:fractionDigits value="2" />
      <xs:minInclusive value="0.00" />
      <xs:maxInclusive value="99999999999.99" />
    </xs:restriction>
  </xs:simpleType>

  <xs:simpleType name="Currency">
        <xs:annotation>
            <xs:documentation>Currency Code: ISO 4217</xs:documentation>
        </xs:annotation>
        <xs:restriction base="xs:string">
            <xs:enumeration value="USD" />
            <xs:enumeration value="UYU" />
            <xs:minLength value="3" />
            <xs:maxLength value="3" />
        </xs:restriction>
    </xs:simpleType>

  <xs:element name="Envelope">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Deposit" minOccurs="1" maxOccurs="1">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="ClientId" type="xs:unsignedLong" />
              <xs:element name="Account" type="xs:unsignedLong" />
              <xs:element name="Currency" type="Currency" />
              <xs:element name="Total" type="Money" />
              <xs:element name="SignedDate" type="xs:date" />
              <xs:element name="Cheques">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element maxOccurs="unbounded" name="Cheque">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element name="Images">
                            <xs:complexType>
                              <xs:sequence>
                                <xs:element name="Front" type="PNGPictureType" />
                                <xs:element name="Back" type="PNGPictureType" />
                              </xs:sequence>
                            </xs:complexType>
                          </xs:element>
                          <xs:element name="MicrCodeCmc" type="xs:string" />
                          <xs:element name="Amount" type="Money" />
                          <xs:element name="PaymentDate" type="xs:date" />
                          <xs:element name="EmissionDate" type="xs:date" />
                        </xs:sequence>
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element xmlns:q1="http://www.w3.org/2000/09/xmldsig#" ref="q1:Signature" />
      </xs:sequence>
      <xs:attribute name="version" type="xs:unsignedByte" use="required" />
    </xs:complexType>
  </xs:element>
</xs:schema>

更新 #1

我尝试了不同的方法,但都没有成功。

在此输入图片描述

即使我将XSD引用到本地文件也不起作用。我看到相同的错误。

 <xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="http://www.w3.org/TR/2002/REC-xmldsig-core-20020212 file:///C:/Temp/xmldsig-core-schema.xsd"/>

更新 #2

即使我使用这种方法,也没有成功。

 public static bool IsValidXml1(string xmlFilePath, string xsdFilePath, string namespaceName)
        {
            XDocument xdoc = null;
            var settings = new XmlReaderSettings();
            settings.DtdProcessing = DtdProcessing.Ignore;
            settings.ProhibitDtd = false;

            try
            {
                using (XmlReader xr = XmlReader.Create(xmlFilePath, settings))
                {
                    xdoc = XDocument.Load(xr);
                    var schemas = new XmlSchemaSet();
                    schemas.Add(namespaceName, xsdFilePath);
                    schemas.Add(@"http://www.w3.org/2000/09/xmldsig#", @"D:\Temp\xmldsig-core-schema.xsd");
                    xdoc.Validate(schemas, null);

                    return true;
                }                
            }
            catch (XmlSchemaValidationException ex)
            {
                // throw;
            }

            return false;
        }

@HenkHolterman 嗯...我必须使用XSD文件来验证XML... - NoWar
@dimi - 你正在将XmlReader修复程序应用于错误的输入文件。 - H H
@HenkHolterman:如果您提供另一种解析命名空间的机制,超出了完整的xs:import所能做的范围,那么您可以在不更改XSD的情况下成功地纠正该问题。然而,最具互操作性的修复方法是完成xs:import就像我展示的那样。然后,OP和其他参与者将能够仅使用XML和XSD进行验证,而无需使用附加机制将导入的XSD绑定到命名空间。如果您能够向XSD修复程序添加特定的XmlReader修复程序,则可能会解决整个问题。 - kjhughes
@HenkHolterman,你可能会对我的解决方案感兴趣,因为它避免了你修改dsig xsd的丑陋方法。 - Evk
1
我已经弄清楚了,并指出了如何修复它。你不需要外部的XmlReader,只需要第二个就可以了。 - H H
@HenkHolterman 嗯,我想我已经阅读了所有的评论,但没有在任何地方找到它。 - Evk
2个回答

10

您非常接近了。在您的XSD文件中,只需替换以下内容:

<xs:import namespace="http://www.w3.org/2000/09/xmldsig#" />

使用

<xs:import namespace="http://www.w3.org/2000/09/xmldsig#" 
           schemaLocation=
    "http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd"/>

通过上述修改添加xs:import/@schemaLocation,您的XSD将不再出现错误,并且您的XML将符合XSD的规范。

说明

XSD可以通过xs:importxs:include进行组合。在这两种情况下,所引用的XSD的位置必须使用必需的schemaLocation属性进行指定,而OP原始的XSD中缺少了此属性。通过如上所示添加xs:import/@schemaLocation,可以消除错误。


更新#1:

当您切换到使用本地XSD时,在您的xs:import中犯了一个错误:

更改为

 <xs:import namespace="http://www.w3.org/2000/09/xmldsig#"
            schemaLocation="http://www.w3.org/TR/2002/REC-xmldsig-core-20020212 
                            file:///C:/Temp/xmldsig-core-schema.xsd"/>

to

 <xs:import namespace="http://www.w3.org/2000/09/xmldsig#"
            schemaLocation="file:///C:/Temp/xmldsig-core-schema.xsd"/>

(您遵循XML文档中具有命名空间位置@xsi:schemaLocation示例;而xs:import/@schemaLocation是不同的。)


更新 #2:

所以我的问题是如何解决它,因为在编辑模式下XML是100%有效的?

也许这就是问题所在。在Visual Studio中编辑XML文件并不会自动针对XSD进行验证。您需要通过代码或验证XML编辑器(例如Oxygen XML EditorXML Spy)进行验证。

此外,您的C#验证代码可能存在问题。请参见Validating an XML against referenced XSD in C#


1
你能解释一下吗?我以前从来没有做过这个。 - H H
@Dimi:上述更正是为了消除您XSD中的错误,一旦完成,您的XML文件将根据您更正后的XSD文件有效。我已经独立确认了这一点,建议您使用独立的XML编辑器对XML文件进行验证,以确保您更新XSD时没有犯错误。 - kjhughes
在浏览器中输入 http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd 并确保您可以连接到模式位置。如果它没有出现,或者花费的时间过长并导致超时,则这就是问题所在。 - kjhughes
1
回答已更新。最后一个提示:强烈建议您首先按照我展示的方式正确编写XML和XSD,然后再考虑C#代码。我已经向您展示了如何修复XSD以使XML验证通过。我需要继续前进 - 您提出了一系列后续问题,而本网站不适用于持续交流。请针对任何未来问题使用单独的问题。谢谢,祝好运。 - kjhughes
显示剩余7条评论

10
如果您不想更改xsd或xml - 请执行以下操作:
  1. (optional) Download xsd from w3 site and save to local disk. W3 site is VERY slow because a lot of software worldwide constantly request those schemas. If you will use that xsd directly - you will often fail by timeout. Some validation tools already have such schemas cached locally, but not .NET validator.

  2. Modify your validation method from UPDATE 2 the following way:

    public static bool IsValidXml1(string xmlFilePath, string xsdFilePath, string namespaceName)
    {
        XDocument xdoc = null;
        var settings = new XmlReaderSettings();
        settings.DtdProcessing = DtdProcessing.Ignore;
    
        try
        {
            using (XmlReader xr = XmlReader.Create(xmlFilePath, settings))
            {
                xdoc = XDocument.Load(xr);
                var schemas = new XmlSchemaSet();                    
                schemas.Add(namespaceName, xsdFilePath);                   
                using (var fs = File.OpenRead(@"D:\Temp\xmldsig-core-schema.xsd")) 
                using (var reader = XmlReader.Create(fs, new XmlReaderSettings() {
                    DtdProcessing = DtdProcessing.Ignore // important
                })) {
                    schemas.Add(@"http://www.w3.org/2000/09/xmldsig#", reader);
                }
    
                xdoc.Validate(schemas, null);
    
                return true;
            }
        }
        catch (XmlSchemaValidationException ex)
        {
            // throw;
        }
    
        return false;
    }
    
你需要使用 XmlReader 添加该模式,而不是直接添加。因为如果你直接添加(如在更新2中) - 它将无法解析 DTD 块,因为当你使用 url(或文件路径)将 XmlSchema 添加到 XmlSchemaSet 中时,它会使用 XmlReaderSettings 读取该文件,并且将 DtdProcessing = DtdProcessing.Prohibit。我们需要将其更改为 DtdProcessing.IgnoreDtdProcessing.Parse。之后,你的验证方法将对目标 xsd 和 xml 文件正常工作,不需要任何更改(并且在 xml 不匹配 xsd 的情况下,它将正确地失败)。

1
第一次就成功了!谢谢,兄弟!愿上帝保佑你! - NoWar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接