lxml - XML 具有多个命名空间的文档
lxml - XML Document with multiple NameSpaces
是否可以使用 lxml 构建一个 XML ?
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns0="http://xmlns.CLT.com/consume/ENTBUS" xmlns:ns1="http://xmlns.CLT.com/Core/ENTBUS" xmlns:ns2="http://xmlns.CLT.com/output/EBO">
<soapenv:Header/>
<soapenv:Body>
<ns0:ConsumptionRequestENTBUS>
<ns1:ENTBUSHeader>
<ns1:ENTBUSID>1</ns1:ENTBUSID>
</ns1:ENTBUSHeader>
<ns0:Zone>
<ns2:Consumption>
<ns2:BusCode>1</ns2:BusCode>
</ns2:Consumption>
</ns0:Zone>
</ns0:ConsumptionRequestENTBUS>
</soapenv:Body>
</soapenv:Envelope>
我尝试如下构建根元素,但失败了。几乎每个元素都需要引用命名空间。
>>> from lxml import etree
>>> root = etree.Element("soapenv:Envelope")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "lxml.etree.pyx", line 2811, in lxml.etree.Element (src\lxml\lxml.etree.c:65389)
File "apihelpers.pxi", line 103, in lxml.etree._makeElement (src\lxml\lxml.etree.c:13898)
File "apihelpers.pxi", line 1575, in lxml.etree._tagValidOrRaise (src\lxml\lxml.etree.c:27955)
ValueError: Invalid tag name u'soapenv:Envelope'
谢谢
lxml 教程确实有一节关于 namespaces。但是,如果您实际上是在与 SOAP 网络服务通信,我建议您尽可能使用合适的库,例如 suds 或 soapbox。
我能够通过以下方式解决这个问题。欢迎提出任何改进建议。
>>> from lxml import etree
>>> SOAPENV_NAMESPACE = "http://schemas.xmlsoap.org/soap/envelope"
>>> SOAPENV = "{%s}" % SOAPENV_NAMESPACE
>>> ns0_NAMESPACE = "http://xmlns.CLT.com/consume/ENTBUS"
>>> ns0 = "{%s}" % ns0_NAMESPACE
>>> ns1_NAMESPACE = "http://xmlns.CLT.com/Core/ENTBUS"
>>> ns1 = "{%s}" % ns1_NAMESPACE
>>> ns2_NAMESPACE = "http://xmlns.CLT.com/output/EBO"
>>> ns2 = "{%s}" % ns2_NAMESPACE
>>> NSMAP = {'SoapEnv' : SOAPENV_NAMESPACE,'ns0':ns0_NAMESPACE,'ns1':ns1_NAMESPACE,'ns2':ns2_NAMESPACE}
>>> envelope = etree.Element(SOAPENV + "Envelope", nsmap=NSMAP)
>>> ConsumptionRequestENTBUS=etree.SubElement(envelope, ns0 + "ConsumptionRequestENTBUS", nsmap=NSMAP)
>>> ENTBUS=etree.SubElement(ConsumptionRequestENTBUS, ns1 + "ENTBUS", nsmap=NSMAP)
>>> ENTBUSHeader=etree.SubElement(ENTBUS, ns1 + "ENTBUSHeader", nsmap=NSMAP)
>>> ENTBUSDetail=etree.SubElement(ENTBUSHeader, ns2 + "ENTBUSDetail", nsmap=NSMAP)
>>> print(etree.tostring(envelope, pretty_print=True))
<SoapEnv:Envelope xmlns:ns0="http://xmlns.CLT.com/consume/ENTBUS" xmlns:ns1="http://xmlns.CLT.com/Core/ENTBUS" xmlns:ns2="h
ttp://xmlns.CLT.com/output/EBO" xmlns:SoapEnv="http://schemas.xmlsoap.org/soap/envelope">
<ns0:ConsumptionRequestENTBUS>
<ns1:ENTBUS>
<ns1:ENTBUSHeader>
<ns2:ENTBUSDetail/>
</ns1:ENTBUSHeader>
</ns1:ENTBUS>
</ns0:ConsumptionRequestENTBUS>
</SoapEnv:Envelope>
是否可以使用 lxml 构建一个 XML ?
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns0="http://xmlns.CLT.com/consume/ENTBUS" xmlns:ns1="http://xmlns.CLT.com/Core/ENTBUS" xmlns:ns2="http://xmlns.CLT.com/output/EBO">
<soapenv:Header/>
<soapenv:Body>
<ns0:ConsumptionRequestENTBUS>
<ns1:ENTBUSHeader>
<ns1:ENTBUSID>1</ns1:ENTBUSID>
</ns1:ENTBUSHeader>
<ns0:Zone>
<ns2:Consumption>
<ns2:BusCode>1</ns2:BusCode>
</ns2:Consumption>
</ns0:Zone>
</ns0:ConsumptionRequestENTBUS>
</soapenv:Body>
</soapenv:Envelope>
我尝试如下构建根元素,但失败了。几乎每个元素都需要引用命名空间。
>>> from lxml import etree
>>> root = etree.Element("soapenv:Envelope")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "lxml.etree.pyx", line 2811, in lxml.etree.Element (src\lxml\lxml.etree.c:65389)
File "apihelpers.pxi", line 103, in lxml.etree._makeElement (src\lxml\lxml.etree.c:13898)
File "apihelpers.pxi", line 1575, in lxml.etree._tagValidOrRaise (src\lxml\lxml.etree.c:27955)
ValueError: Invalid tag name u'soapenv:Envelope'
谢谢
lxml 教程确实有一节关于 namespaces。但是,如果您实际上是在与 SOAP 网络服务通信,我建议您尽可能使用合适的库,例如 suds 或 soapbox。
我能够通过以下方式解决这个问题。欢迎提出任何改进建议。
>>> from lxml import etree
>>> SOAPENV_NAMESPACE = "http://schemas.xmlsoap.org/soap/envelope"
>>> SOAPENV = "{%s}" % SOAPENV_NAMESPACE
>>> ns0_NAMESPACE = "http://xmlns.CLT.com/consume/ENTBUS"
>>> ns0 = "{%s}" % ns0_NAMESPACE
>>> ns1_NAMESPACE = "http://xmlns.CLT.com/Core/ENTBUS"
>>> ns1 = "{%s}" % ns1_NAMESPACE
>>> ns2_NAMESPACE = "http://xmlns.CLT.com/output/EBO"
>>> ns2 = "{%s}" % ns2_NAMESPACE
>>> NSMAP = {'SoapEnv' : SOAPENV_NAMESPACE,'ns0':ns0_NAMESPACE,'ns1':ns1_NAMESPACE,'ns2':ns2_NAMESPACE}
>>> envelope = etree.Element(SOAPENV + "Envelope", nsmap=NSMAP)
>>> ConsumptionRequestENTBUS=etree.SubElement(envelope, ns0 + "ConsumptionRequestENTBUS", nsmap=NSMAP)
>>> ENTBUS=etree.SubElement(ConsumptionRequestENTBUS, ns1 + "ENTBUS", nsmap=NSMAP)
>>> ENTBUSHeader=etree.SubElement(ENTBUS, ns1 + "ENTBUSHeader", nsmap=NSMAP)
>>> ENTBUSDetail=etree.SubElement(ENTBUSHeader, ns2 + "ENTBUSDetail", nsmap=NSMAP)
>>> print(etree.tostring(envelope, pretty_print=True))
<SoapEnv:Envelope xmlns:ns0="http://xmlns.CLT.com/consume/ENTBUS" xmlns:ns1="http://xmlns.CLT.com/Core/ENTBUS" xmlns:ns2="h
ttp://xmlns.CLT.com/output/EBO" xmlns:SoapEnv="http://schemas.xmlsoap.org/soap/envelope">
<ns0:ConsumptionRequestENTBUS>
<ns1:ENTBUS>
<ns1:ENTBUSHeader>
<ns2:ENTBUSDetail/>
</ns1:ENTBUSHeader>
</ns1:ENTBUS>
</ns0:ConsumptionRequestENTBUS>
</SoapEnv:Envelope>