如何在python中使用ElementTree将xml元素获取为带有名称空间的字符串?

时间:2018-11-21 05:25:26

标签: python xml elementtree

我需要从xml中获取字符串形式的元素。我正在尝试使用以下xml格式。

<xml>
    <prot:data xmlns:prot="prot">
        <product-id-template>
            <prot:ProductId>PRODUCT_ID</prot:ProductId>
        </product-id-template>

        <product-name-template>
            <prot:ProductName>PRODUCT_NAME</prot:ProductName>
        </product-name-template>

        <dealer-template>
            <xsi:Dealer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">DEALER</xsi:Dealer>
        </dealer-template>
    </prot:data>
</xml>

我尝试了以下代码:

from xml.etree import ElementTree as ET

def get_template(xpath, namespaces):   
    tree = ET.parse('cdata.xml')
    elements = tree.getroot()
    for element in elements.findall(xpath, namespaces=namespaces):
        return element

namespace = {"prot" : "prot"}
aa = get_template(".//prot:ProductId", namespace)
print(ET.tostring(aa).decode())

实际输出:

<ns0:ProductId xmlns:ns0="prot">PRODUCT_ID</ns0:ProductId>

预期输出:

<prot:ProductId>PRODUCT_ID</prot:ProductId>

我不应该从文档中出现的xmlns中删除它。而且必须在不存在的地方将其删除。示例product-id-template不包含xmlns,因此需要在没有xmlns的情况下进行检索。并且dealer-template包含xmlns,因此需要使用xmlns进行检索。

如何实现?

1 个答案:

答案 0 :(得分:1)

您可以使用正则表达式删除 xmlns

Private Sub cmdDelete_click()
Dim sql As String, rCount As Integer
If me.dirty then
Me.dirty = False
End if
Set dbs = currentdb
SQL = “DELETE Item FROM item = ‘“ & me.txtItem & “‘“ &                  “WHERE ID=“ & me.txtID2

Dbs.Execute sql, dbFailOnError
rCount = dbs.RecordsAffected
If rCount >0 then
Msgbox “The item List has been updated”
List40.Requery
Clear
End if
End sub

更新:您可以做一个非常疯狂的事情。尽管我不推荐它,因为我不是Python专家。

我刚刚检查了源代码,发现我可以做到这一点:

import re
# ...
with_ns = ET.tostring(aa).decode()
no_ns = re.sub(' xmlns(:\w+)?="[^"]+"', '', with_ns)
print(no_ns)

我刚刚定义了def my_serialize_xml(write, elem, qnames, namespaces, short_empty_elements, **kwargs): ET._serialize_xml(write, elem, qnames, None, short_empty_elements, **kwargs) ET._serialize["xml"] = my_serialize_xml ,它用my_serialize_xml调用ElementTree._serialize_xml。然后,在字典namespaces=None中,我将键ElementTree._serialize的值更改为"xml"。因此,当您致电my_serialize_xml时,它将使用ElementTree.tostring

如果要尝试,只需将代码放在(my_serialize_xml之后)(但使用from xml.etree import ElementTree as ET之前)。