When calling lxml.etree.canonicalize(node)
a ValueError exception is raised: Namespace "{<uri>}" of name "<name>" is not declared in scope.
In this particular case the message is ValueError: Namespace "http://schemas.xmlsoap.org/soap/envelope/" of name "Header" is not declared in scope
The following code works exactly as expected:
from lxml import etree as ET
url_soap_envelope = "http://schemas.xmlsoap.org/soap/envelope/"
# Header
nsmap_Header = {
's': url_soap_envelope,
}
qname_s_Header = ET.QName(url_soap_envelope, "Header")
node_header = ET.Element(qname_s_Header, nsmap=nsmap_Header)
ET.canonicalize(node_header)
# '<s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"></s:Header>'
However, if node_header
is a subelement of another node, it breaks:
from lxml import etree as ET
url_wss_u = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
url_soap_envelope = "http://schemas.xmlsoap.org/soap/envelope/"
# Envelope
nsmap_Envelope = {
's': url_soap_envelope,
'u': url_wss_u,
}
qname_s_Envelope = ET.QName(url_soap_envelope, "Envelope")
node_envelope = ET.Element(qname_s_Envelope, {}, nsmap=nsmap_Envelope)
# Envelope / Header
nsmap_Header = {
's': url_soap_envelope,
}
qname_s_Header = ET.QName(url_soap_envelope, "Header")
node_header = ET.SubElement(node_envelope, qname_s_Header, nsmap=nsmap_Header)
ET.canonicalize(node_envelope)
# '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Header></s:Header></s:Envelope>'
ET.canonicalize(node_header)
Error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "src/lxml/serializer.pxi", line 918, in lxml.etree.canonicalize
File "src/lxml/serializer.pxi", line 943, in lxml.etree._tree_to_target
File "src/lxml/serializer.pxi", line 1128, in lxml.etree.C14NWriterTarget.start
File "src/lxml/serializer.pxi", line 1155, in lxml.etree.C14NWriterTarget._start
File "src/lxml/serializer.pxi", line 1085, in lxml.etree.C14NWriterTarget._qname
ValueError: Namespace "http://schemas.xmlsoap.org/soap/envelope/" of name "Header" is not declared in scope
The expected result when calling ET.canonicalize(node_header)
is '<s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"></s:Header>'
The XML I'm trying to build has the following template:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>{created}
</u:Created>
<u:Expires>{expires}
</u:Expires>
</u:Timestamp>
<o:BinarySecurityToken u:Id="{uuid}" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">{b64certificate}
</o:BinarySecurityToken>
<Signature xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1"/>
<Reference URI="#_0">
<Transforms>
<Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/>
</Transforms>
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1"/>
<DigestValue>{digest_value}
</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>{b64signature}
</SignatureValue>
<KeyInfo>
<o:SecurityTokenReference>
<o:Reference ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" URI="#{uuid}"/>
</o:SecurityTokenReference>
</KeyInfo>
</Signature>
</o:Security>
</s:Header>
<s:Body>
<Autentica xmlns="http://DescargaMasivaTerceros.gob.mx"/>
</s:Body>
</s:Envelope>