Python LXML创建具有特定命名空间和结构的xml

时间:2017-12-20 12:54:33

标签: python lxml

我正在尝试从python应用程序创建XML导出,并且需要以特定方式为文件的外部收件人构建文件。

根节点需要命名空间,但子节点不应该。

根节点应如下所示:

<ns0:SalesInvoice_Custom_Xml xmlns:ns0="http://EDI-export/Invoice">...</ns0:SalesInvoice_Custom_Xml>

我曾尝试使用Python 2.7上的lxml库生成相同的节点,但它的行为并不像预期的那样。

以下是应该生成根节点的代码:

def create_edi(self, document):
    _logger.info("INFO: Started creating EDI invoice with invoice number %s", document.number)
    rootNs = etree.QName("ns0", "SalesInvoice_Custom_Xml")
    doc = etree.Element(rootNs, nsmap={
        'ns0': "http://EDI-export/Invoice"
    })

这给出了以下输出

<ns1:SalesInvoice_Custom_Xml xmlns:ns0="http://EDI-export/Invoice" xmlns:ns1="ns0">...</ns1:SalesInvoice_Custom_Xml>

我应该在代码中更改什么才能让lxml生成正确的根节点

1 个答案:

答案 0 :(得分:1)

您需要使用

rootNs = etree.QName(ns0, "SalesInvoice_Custom_Xml")

ns0 = "http://EDI-export/Invoice"

整个数据结构本身与您稍后可能应用的任何命名空间映射无关,即。即标签知道真正的名称空间(例如http://EDI-export/Invoice)而不是他们的映射(例如ns0)。

稍后,当您最终将其序列化为字符串时,需要命名空间映射。 然后(并且只有这样)才会使用命名空间映射。

此外,在解析之后,您可以询问etree对象在解析期间找到了什么命名空间映射。但这不是结构的一部分,它只是关于结构如何编码为字符串的附加信息。请考虑以下两个XML在逻辑上是相同的:

<x:tag xmlns:x="namespace"></x:tag>

<y:tag xmlns:y="namespace"></y:tag>

解析后,它们的结构将是相同的,它们的命名空间映射不会。