我有一个使用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>
Run Code Online (Sandbox Code Playgroud)
我使用下面代码的当前结果是:(调用创建的文件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>
Run Code Online (Sandbox Code Playgroud)
我想修复两件事(如果有可能使用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
Run Code Online (Sandbox Code Playgroud)
这是我更新狗数并将其保存到新文件的代码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')
Run Code Online (Sandbox Code Playgroud)
不幸的是,往返并不是一个小问题。对于 XML,通常不可能保留原始文档,除非您使用特殊的解析器(例如DecentXML,但那是针对 Java 的)。
根据您的需求,您有以下选择:
如果您控制源代码并且可以通过单元测试保护代码,则可以编写自己的简单解析器。该解析器不接受 XML,只接受有限的子集。例如,您可以将整个文档作为字符串读取,然后使用 Python 的字符串操作来查找<dogs>和替换下一个<. 黑客?是的。
您可以过滤输出。XML 只允许该字符串<ns0:出现在一处,因此您可以搜索并替换它<,然后使用<group xmlns:ns0="→进行相同的操作<group xmlns="。这是相当安全的,除非您可以在 XML 中包含CDATA 。
您可以编写自己的简单 XML 解析器。将输入读取为字符串,然后为每对及其<>在输入中的位置创建元素。这允许您快速分解输入,但仅适用于小输入。
| 归档时间: |
|
| 查看次数: |
7508 次 |
| 最近记录: |