调用
lxml.etree.canonicalize(node)
时引发 ValueError 异常:名称“在这种特殊情况下,消息是
ValueError: Namespace "http://schemas.xmlsoap.org/soap/envelope/" of name "Header" is not declared in scope
以下代码完全符合预期:
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>'
但是,如果
node_header
是另一个节点的子元素,它会中断:
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)
# 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
调用时的预期结果
ET.canonicalize(node_header)
是'<s:Header xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"></s:Header>'