使用ElementT在python3中处理XML命名空间

2024-04-23 17:59:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个输入XML带有一些错误的名称空间。我试图用ElementTree修复它们,但没有成功

输入示例:(这里ns0:可以是ns:,p:,n:etc…)你知道吗

<ns0:Invoice xmlns:ns0="http://invoices.com/docs/xsd/invoices/v1.2" version="FPR12">

  <InvoiceHeader>
    <DataH>data header</DataH>
  </InvoiceHeader>

  <InvoiceBody>
    <DataB>data body</DataB>
  </InvoiceBody>

</ns0:Invoice>

需要输出文件:(根目录中的命名空间必须没有前缀,并且某些内部标记声明为xmlns=“”)

<Invoice xmlns:"http://invoices.com/docs/xsd/invoices/v1.2" version="FPR12">

  <InvoiceHeader xmlns="">
    <DataH>data header</DataH>
  </InvoiceHeader>

  <InvoiceBody xmlns="">
    <DataB>data body</DataB>
  </InvoiceBody>

</Invoice>

我尝试如下所示更改根命名空间,但结果文件没有更改

import xml.etree.ElementTree as ET

tree = ET.parse('./cache/test.xml')
root = tree.getroot()

root.tag = '{http://invoices.com/docs/xsd/invoices/v1.2}Invoice'
xml = ET.tostring(root, encoding="unicode")
with open('./cache/output.xml', 'wt') as f:
    f.write(xml)

当你试着

changing root.tag  = 'Invoice'

它生成一个完全没有名称空间的标记

请让我知道我是否犯了任何错误,或者我应该切换到另一个库,或者尝试用正则表达式替换字符串

提前谢谢


Tags: comhttpdocsdata空间invoicerootxml
1条回答
网友
1楼 · 发布于 2024-04-23 17:59:36

现在不知道它是否对任何人有用,但我使用lxml和以下代码修复了名称空间。你知道吗

from lxml import etree
from copy import deepcopy

tree = etree.parse('./cache/test.xml')

# create a new root without prefix in the namespace
NSMAP = {None : "http://invoices.com/docs/xsd/invoices/v1.2"}
root = etree.Element("{http://invoices.com/docs/xsd/invoices/v1.2}Invoice", nsmap = NSMAP)

# copy attributes from original root
for attr, value in tree.getroot().items():
    root.set(attr,value)

# deep copy of children (adding empty namespace in some tags)
for child in tree.getroot().getchildren():
    if child.tag in( 'InvoiceHeader', 'InvoiceBody'):
        child.set("xmlns","")
    root.append( deepcopy(child) )

xml = etree.tostring(root, pretty_print=True)
with open('./cache/output.xml', 'wb') as f:
    f.write(xml)

相关问题 更多 >