如何使用多个XSD验证XML

发布于 2025-01-29 22:46:27 字数 27926 浏览 4 评论 0原文

我需要验证使用两个XSD文件生成的XML。我之所以挣扎,是因为XSD文件之一引用了另一个文件,因此我因此遇到了错误。

以下是“发票架构”:

<?xml version="1.0" encoding="utf-8"?>
<!-- XSD ver.23/08/2021 -->
<xs:schema xmlns:ds="http://www.w3.org/2000/09/xmldsig#" attributeFormDefault="unqualified"
           elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="../SignatureSchema.xsd"/>
    <xs:element name="facturaElectronicaCompraVenta">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="cabecera">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="nitEmisor">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="1"/>
                                        <xs:maxInclusive value="9999999999999"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="razonSocialEmisor">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="200"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="municipio">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="25"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="telefono" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="25"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="numeroFactura">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="1"/>
                                        <xs:maxInclusive value="9999999999"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="cuf">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="100"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="cufd">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="100"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="codigoSucursal">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="0"/>
                                        <xs:maxInclusive value="9999"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="direccion">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="500"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="codigoPuntoVenta" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="0"/>
                                        <xs:maxInclusive value="9999"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="fechaEmision" type="xs:dateTime"/>
                            <xs:element name="nombreRazonSocial" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="500"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="codigoTipoDocumentoIdentidad">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="1"/>
                                        <xs:maxInclusive value="5"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="numeroDocumento">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="20"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="complemento" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:maxLength value="5"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="codigoCliente">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="100"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="codigoMetodoPago">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="1"/>
                                        <xs:maxInclusive value="308"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="numeroTarjeta" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="0"/>
                                        <xs:maxInclusive value="9999999999999999"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="montoTotal">
                                <xs:simpleType>
                                    <xs:restriction base="xs:decimal">
                                        <xs:totalDigits value="17"/>
                                        <xs:fractionDigits value="2"/>
                                        <xs:minExclusive value="0"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="montoTotalSujetoIva">
                                <xs:simpleType>
                                    <xs:restriction base="xs:decimal">
                                        <xs:totalDigits value="17"/>
                                        <xs:fractionDigits value="2"/>
                                        <xs:minInclusive value="0"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="codigoMoneda">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="1"/>
                                        <xs:maxInclusive value="154"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="tipoCambio">
                                <xs:simpleType>
                                    <xs:restriction base="xs:decimal">
                                        <xs:totalDigits value="17"/>
                                        <xs:fractionDigits value="2"/>
                                        <xs:minExclusive value="0"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="montoTotalMoneda">
                                <xs:simpleType>
                                    <xs:restriction base="xs:decimal">
                                        <xs:totalDigits value="17"/>
                                        <xs:fractionDigits value="2"/>
                                        <xs:minExclusive value="0"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="montoGiftCard" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:decimal">
                                        <xs:totalDigits value="17"/>
                                        <xs:fractionDigits value="2"/>
                                        <xs:minInclusive value="0"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="descuentoAdicional" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:decimal">
                                        <xs:totalDigits value="17"/>
                                        <xs:fractionDigits value="2"/>
                                        <xs:minInclusive value="0"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="codigoExcepcion" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="0"/>
                                        <xs:maxInclusive value="1"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="cafc" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="50"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="leyenda">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="200"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="usuario">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="100"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="codigoDocumentoSector" type="xs:integer" fixed="1"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="detalle" minOccurs="1" maxOccurs="500">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="actividadEconomica">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="10"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="codigoProductoSin">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="1"/>
                                        <xs:maxInclusive value="99999999"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="codigoProducto">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="50"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="descripcion">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="500"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="cantidad">
                                <xs:simpleType>
                                    <xs:restriction base="xs:decimal">
                                        <xs:totalDigits value="17"/>
                                        <xs:fractionDigits value="2"/>
                                        <xs:minExclusive value="0"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="unidadMedida">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="1"/>
                                        <xs:maxInclusive value="86"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="precioUnitario">
                                <xs:simpleType>
                                    <xs:restriction base="xs:decimal">
                                        <xs:totalDigits value="17"/>
                                        <xs:fractionDigits value="2"/>
                                        <xs:minExclusive value="0"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="montoDescuento" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:decimal">
                                        <xs:totalDigits value="17"/>
                                        <xs:fractionDigits value="2"/>
                                        <xs:minInclusive value="0"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="subTotal">
                                <xs:simpleType>
                                    <xs:restriction base="xs:decimal">
                                        <xs:totalDigits value="17"/>
                                        <xs:fractionDigits value="2"/>
                                        <xs:minExclusive value="0"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="numeroSerie" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="0"/>
                                        <xs:maxLength value="1500"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="numeroImei" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="0"/>
                                        <xs:maxLength value="1500"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element ref="ds:Signature"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

以下是“签名架构”:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tns="http://www.w3.org/2000/09/xmldsig#" attributeFormDefault="unqualified"
           elementFormDefault="qualified" targetNamespace="http://www.w3.org/2000/09/xmldsig#"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="Signature">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="SignedInfo">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="CanonicalizationMethod">
                                <xs:complexType>
                                    <xs:attribute name="Algorithm" type="xs:string" use="required"/>
                                </xs:complexType>
                            </xs:element>
                            <xs:element name="SignatureMethod">
                                <xs:complexType>
                                    <xs:attribute name="Algorithm" type="xs:string" use="required"/>
                                </xs:complexType>
                            </xs:element>
                            <xs:element name="Reference">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element name="Transforms">
                                            <xs:complexType>
                                                <xs:sequence>
                                                    <xs:element maxOccurs="unbounded" name="Transform">
                                                        <xs:complexType>
                                                            <xs:attribute name="Algorithm" type="xs:string"
                                                                          use="required"/>
                                                        </xs:complexType>
                                                    </xs:element>
                                                </xs:sequence>
                                            </xs:complexType>
                                        </xs:element>
                                        <xs:element name="DigestMethod">
                                            <xs:complexType>
                                                <xs:attribute name="Algorithm" type="xs:string" use="required"/>
                                            </xs:complexType>
                                        </xs:element>
                                        <xs:element name="DigestValue" type="xs:string"/>
                                    </xs:sequence>
                                    <xs:attribute name="URI" type="xs:string" use="required"/>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="SignatureValue" type="xs:string"/>
                <xs:element name="KeyInfo">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="X509Data">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element name="X509Certificate" type="xs:string"/>
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

“发票架构”引用“签名架构”,“签名架构”带有名称空间“示意图”到以下位置“ ../ signatureschema.xssd”。 我正在与ODOO合作,并在“ myModule/data/xsd/sale_purchase”和“签名架构“ uder” mymodule/data/xsd/“”下存储“发票架构”文件。

因此,我使用以下代码验证文件:

    def _validate_invoice_xml(self):
        root = self._get_xml_tree_root()
        # Validate generated xml
        xsd_file_path = get_module_resource('MyModule', 'data/xsd/sale_purchase', 'InvoiceSchema.xsd')
        with open(xsd_file_path) as xsd_file:
            invoice_schema = xsd_file.read()
        # Decode XSD file
        invoice_xsd = ET.fromstring(invoice_schema.encode('ascii'))
        xmlschema = ET.XMLSchema(invoice_xsd)
        validation_result = xmlschema.validate(root)
        if not validation_result:
            log = xmlschema.error_log
            error = log.last_error
            raise exceptions.ValidationError('XML file validation error:' + '\n' + str(error.message))

但是,当我运行代码时,我会收到以下错误:

lxml.etree.XMLSchemaParseError: Element '{http://www.w3.org/2001/XMLSchema}element', attribute 'ref': The QName value '{http://www.w3.org/2000/09/xmldsig#}Signature' does not resolve to a(n) element declaration., line 344

我相信该错误与使用schemalocation =“ ../ signatureschema.xsd”的“ signaute架构”引用有关。但是我不确定,这些文件是否位于应有的位置。

为什么我会遇到此错误?如何避免它?

I need to validate an xml that I generate with two XSD files provided. I am struggling because one of the XSD files references the other one and it looks that I am getting errors because of that.

The following is the "Invoice schema":

<?xml version="1.0" encoding="utf-8"?>
<!-- XSD ver.23/08/2021 -->
<xs:schema xmlns:ds="http://www.w3.org/2000/09/xmldsig#" attributeFormDefault="unqualified"
           elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="../SignatureSchema.xsd"/>
    <xs:element name="facturaElectronicaCompraVenta">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="cabecera">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="nitEmisor">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="1"/>
                                        <xs:maxInclusive value="9999999999999"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="razonSocialEmisor">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="200"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="municipio">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="25"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="telefono" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="25"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="numeroFactura">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="1"/>
                                        <xs:maxInclusive value="9999999999"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="cuf">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="100"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="cufd">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="100"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="codigoSucursal">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="0"/>
                                        <xs:maxInclusive value="9999"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="direccion">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="500"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="codigoPuntoVenta" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="0"/>
                                        <xs:maxInclusive value="9999"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="fechaEmision" type="xs:dateTime"/>
                            <xs:element name="nombreRazonSocial" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="500"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="codigoTipoDocumentoIdentidad">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="1"/>
                                        <xs:maxInclusive value="5"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="numeroDocumento">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="20"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="complemento" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:maxLength value="5"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="codigoCliente">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="100"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="codigoMetodoPago">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="1"/>
                                        <xs:maxInclusive value="308"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="numeroTarjeta" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="0"/>
                                        <xs:maxInclusive value="9999999999999999"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="montoTotal">
                                <xs:simpleType>
                                    <xs:restriction base="xs:decimal">
                                        <xs:totalDigits value="17"/>
                                        <xs:fractionDigits value="2"/>
                                        <xs:minExclusive value="0"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="montoTotalSujetoIva">
                                <xs:simpleType>
                                    <xs:restriction base="xs:decimal">
                                        <xs:totalDigits value="17"/>
                                        <xs:fractionDigits value="2"/>
                                        <xs:minInclusive value="0"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="codigoMoneda">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="1"/>
                                        <xs:maxInclusive value="154"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="tipoCambio">
                                <xs:simpleType>
                                    <xs:restriction base="xs:decimal">
                                        <xs:totalDigits value="17"/>
                                        <xs:fractionDigits value="2"/>
                                        <xs:minExclusive value="0"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="montoTotalMoneda">
                                <xs:simpleType>
                                    <xs:restriction base="xs:decimal">
                                        <xs:totalDigits value="17"/>
                                        <xs:fractionDigits value="2"/>
                                        <xs:minExclusive value="0"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="montoGiftCard" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:decimal">
                                        <xs:totalDigits value="17"/>
                                        <xs:fractionDigits value="2"/>
                                        <xs:minInclusive value="0"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="descuentoAdicional" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:decimal">
                                        <xs:totalDigits value="17"/>
                                        <xs:fractionDigits value="2"/>
                                        <xs:minInclusive value="0"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="codigoExcepcion" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="0"/>
                                        <xs:maxInclusive value="1"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="cafc" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="50"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="leyenda">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="200"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="usuario">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="100"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="codigoDocumentoSector" type="xs:integer" fixed="1"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="detalle" minOccurs="1" maxOccurs="500">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="actividadEconomica">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="10"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="codigoProductoSin">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="1"/>
                                        <xs:maxInclusive value="99999999"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="codigoProducto">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="50"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="descripcion">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="1"/>
                                        <xs:maxLength value="500"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="cantidad">
                                <xs:simpleType>
                                    <xs:restriction base="xs:decimal">
                                        <xs:totalDigits value="17"/>
                                        <xs:fractionDigits value="2"/>
                                        <xs:minExclusive value="0"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="unidadMedida">
                                <xs:simpleType>
                                    <xs:restriction base="xs:integer">
                                        <xs:minInclusive value="1"/>
                                        <xs:maxInclusive value="86"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="precioUnitario">
                                <xs:simpleType>
                                    <xs:restriction base="xs:decimal">
                                        <xs:totalDigits value="17"/>
                                        <xs:fractionDigits value="2"/>
                                        <xs:minExclusive value="0"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="montoDescuento" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:decimal">
                                        <xs:totalDigits value="17"/>
                                        <xs:fractionDigits value="2"/>
                                        <xs:minInclusive value="0"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="subTotal">
                                <xs:simpleType>
                                    <xs:restriction base="xs:decimal">
                                        <xs:totalDigits value="17"/>
                                        <xs:fractionDigits value="2"/>
                                        <xs:minExclusive value="0"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="numeroSerie" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="0"/>
                                        <xs:maxLength value="1500"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                            <xs:element name="numeroImei" nillable="true">
                                <xs:simpleType>
                                    <xs:restriction base="xs:string">
                                        <xs:minLength value="0"/>
                                        <xs:maxLength value="1500"/>
                                    </xs:restriction>
                                </xs:simpleType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element ref="ds:Signature"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

And the following one is the "Signature schema":

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:tns="http://www.w3.org/2000/09/xmldsig#" attributeFormDefault="unqualified"
           elementFormDefault="qualified" targetNamespace="http://www.w3.org/2000/09/xmldsig#"
           xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="Signature">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="SignedInfo">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="CanonicalizationMethod">
                                <xs:complexType>
                                    <xs:attribute name="Algorithm" type="xs:string" use="required"/>
                                </xs:complexType>
                            </xs:element>
                            <xs:element name="SignatureMethod">
                                <xs:complexType>
                                    <xs:attribute name="Algorithm" type="xs:string" use="required"/>
                                </xs:complexType>
                            </xs:element>
                            <xs:element name="Reference">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element name="Transforms">
                                            <xs:complexType>
                                                <xs:sequence>
                                                    <xs:element maxOccurs="unbounded" name="Transform">
                                                        <xs:complexType>
                                                            <xs:attribute name="Algorithm" type="xs:string"
                                                                          use="required"/>
                                                        </xs:complexType>
                                                    </xs:element>
                                                </xs:sequence>
                                            </xs:complexType>
                                        </xs:element>
                                        <xs:element name="DigestMethod">
                                            <xs:complexType>
                                                <xs:attribute name="Algorithm" type="xs:string" use="required"/>
                                            </xs:complexType>
                                        </xs:element>
                                        <xs:element name="DigestValue" type="xs:string"/>
                                    </xs:sequence>
                                    <xs:attribute name="URI" type="xs:string" use="required"/>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
                <xs:element name="SignatureValue" type="xs:string"/>
                <xs:element name="KeyInfo">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="X509Data">
                                <xs:complexType>
                                    <xs:sequence>
                                        <xs:element name="X509Certificate" type="xs:string"/>
                                    </xs:sequence>
                                </xs:complexType>
                            </xs:element>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

The "Invoice schema" references the "Signature schema" with the namespace "schemaLocation" to the following location "../SignatureSchema.xsd".
I am working with Odoo and I am storing the "Invoice schema" file under "MyModule/data/xsd/sale_purchase" and the "Signature schema" uder "MyModule/data/xsd/".

So I validate my files with the following code:

    def _validate_invoice_xml(self):
        root = self._get_xml_tree_root()
        # Validate generated xml
        xsd_file_path = get_module_resource('MyModule', 'data/xsd/sale_purchase', 'InvoiceSchema.xsd')
        with open(xsd_file_path) as xsd_file:
            invoice_schema = xsd_file.read()
        # Decode XSD file
        invoice_xsd = ET.fromstring(invoice_schema.encode('ascii'))
        xmlschema = ET.XMLSchema(invoice_xsd)
        validation_result = xmlschema.validate(root)
        if not validation_result:
            log = xmlschema.error_log
            error = log.last_error
            raise exceptions.ValidationError('XML file validation error:' + '\n' + str(error.message))

But when I run my code I get the following error:

lxml.etree.XMLSchemaParseError: Element '{http://www.w3.org/2001/XMLSchema}element', attribute 'ref': The QName value '{http://www.w3.org/2000/09/xmldsig#}Signature' does not resolve to a(n) element declaration., line 344

I believe that the error is related with the referencing of the "Signaute schema" with schemaLocation="../SignatureSchema.xsd". But I am not sure, the files are located where they should.

Why am I getting this error and how can I avoid it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

走走停停 2025-02-05 22:46:27

正如迈克尔·凯(Michael Kay)所说的那样,我需要获得XSD文件的绝对路径。在ODOO中,我通过使用以下代码来完成此操作:

import os

# This gets the location of the absolute location of the python file running
current_location = os.path.dirname(os.path.realpath(__file__))
# Replacing part of the path to point to the XSD file location
schema_file_location = current_location.replace('models', 'data/pathToMyXSDfile.xsd')
# Validate XML file
xsd_file = ET.parse(schema_file_location)
xmlschema = ET.XMLSchema(xsd_file)
validation_result = xmlschema.validate(root)

As Michael Kay commented, I needed to get the absolute path to the XSD file. In odoo I have managed to do it by using the following code:

import os

# This gets the location of the absolute location of the python file running
current_location = os.path.dirname(os.path.realpath(__file__))
# Replacing part of the path to point to the XSD file location
schema_file_location = current_location.replace('models', 'data/pathToMyXSDfile.xsd')
# Validate XML file
xsd_file = ET.parse(schema_file_location)
xmlschema = ET.XMLSchema(xsd_file)
validation_result = xmlschema.validate(root)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文