使用lxm从python中的xml中删除名称空间和前缀

2024-05-05 12:48:32 发布

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

我有一个xml文件需要打开并对其进行一些更改,其中一个更改是删除名称空间和前缀,然后保存到另一个文件。 以下是xml:

<?xml version='1.0' encoding='UTF-8'?>
<package xmlns="http://apple.com/itunes/importer">
  <provider>some data</provider>
  <language>en-GB</language>
</package>

我可以做其他需要的更改,但找不到如何删除名称空间和前缀。这是我需要的重用xml:

<?xml version='1.0' encoding='UTF-8'?>
<package>
  <provider>some data</provider>
  <language>en-GB</language>
</package>

下面是我的脚本,它将打开并解析xml并保存它:

metadata = '/Users/user1/Desktop/Python/metadata.xml'
from lxml import etree
parser = etree.XMLParser(remove_blank_text=True)
open(metadata)
tree = etree.parse(metadata, parser)
root = tree.getroot()
tree.write('/Users/user1/Desktop/Python/done.xml', pretty_print = True, xml_declaration = True, encoding = 'UTF-8')

那么我该如何在脚本中添加代码来删除名称空间和前缀呢?


Tags: 文件名称truetreepackageversion空间some
3条回答
import xml.etree.ElementTree as ET
def remove_namespace(doc, namespace):
    """Remove namespace in the passed document in place."""
    ns = u'{%s}' % namespace
    nsl = len(ns)
    for elem in doc.getiterator():
        if elem.tag.startswith(ns):
            elem.tag = elem.tag[nsl:]

metadata = '/Users/user1/Desktop/Python/metadata.xml'
tree = ET.parse(metadata)
root = tree.getroot()

remove_namespace(root, u'http://apple.com/itunes/importer')
tree.write('/Users/user1/Desktop/Python/done.xml',
       pretty_print=True, xml_declaration=True, encoding='UTF-8')

使用了here中的代码片段 通过搜索以“xmlns”开头的标记,可以很容易地扩展此方法以删除任何命名空间属性

>>> root.tag
'{http://latest/nmc-omc/cmNrm.doc#measCollec}measCollecFile'
>>> etree.QName(root.tag).localname
'measCollecFile'

source

附录:lxml.etree.QName也接受构造元素。因此etree.QName(root.tag).localname相当于:

etree.QName(root).localname

按照Uku Loskit的建议更换标签。除此之外,还可以使用lxml.objectify.deannotate

from lxml import etree, objectify

metadata = '/Users/user1/Desktop/Python/metadata.xml'
parser = etree.XMLParser(remove_blank_text=True)
tree = etree.parse(metadata, parser)
root = tree.getroot()

####    
for elem in root.getiterator():
    if not hasattr(elem.tag, 'find'): continue  # (1)
    i = elem.tag.find('}')
    if i >= 0:
        elem.tag = elem.tag[i+1:]
objectify.deannotate(root, cleanup_namespaces=True)
####

tree.write('/Users/user1/Desktop/Python/done.xml',
           pretty_print=True, xml_declaration=True, encoding='UTF-8')

更新

某些标记(如Comment)在访问tag属性时返回函数。增加了一个守卫。(一)

相关问题 更多 >