【发布时间】:2012-03-23 16:41:18
【问题描述】:
我有一个使用 XML 命名空间的文档,我想将其 /group/house/dogs 加一:(该文件名为 houses.xml)
<?xml version="1.0"?>
<group xmlns="http://dogs.house.local">
<house>
<id>2821</id>
<dogs>2</dogs>
</house>
</group>
我当前使用以下代码的结果是:(创建的文件名为houses2.xml)
<ns0:group xmlns:ns0="http://dogs.house.local">
<ns0:house>
<ns0:id>2821</ns0:id>
<ns0:dogs>3</ns0:dogs>
</ns0:house>
</ns0:group>
我想解决两件事(如果可以使用 ElementTree。如果不是,我会很高兴提出我应该改用什么的建议):
- 我想保留
<?xml version="1.0"?>这一行。 - 我不想为所有标签添加前缀,我想保持原样。
总之,我不想过多地弄乱文档。
生成上述结果的我当前的代码(除上述缺陷外都有效)如下。
我制作了一个实用函数,它使用 ElementTree 加载 XML 文件并返回 elementTree 和命名空间(因为我不想对命名空间进行硬编码,并且愿意承担它所暗示的风险):
def elementTreeRootAndNamespace(xml_file):
from xml.etree import ElementTree
import re
element_tree = ElementTree.parse(xml_file)
# Search for a namespace on the root tag
namespace_search = re.search('^({\S+})', element_tree.getroot().tag)
# Keep the namespace empty if none exists, if a namespace exists set
# namespace to {namespacename}
namespace = ''
if namespace_search:
namespace = namespace_search.group(1)
return element_tree, namespace
这是我更新狗数量并将其保存到新文件houses2.xml的代码:
elementTree, namespace = elementTreeRootAndNamespace('houses.xml')
# Insert the namespace before each tag when when finding current number of dogs,
# as ElementTree requires the namespace to be prefixed within {...} when a
# namespace is used in the document.
dogs = elementTree.find('{ns}house/{ns}dogs'.format(ns = namespace))
# Increase the number of dogs by one
dogs.text = str(int(dogs.text) + 1)
# Write the result to the new file houses2.xml.
elementTree.write('houses2.xml')
【问题讨论】: