我有一个XML文件,该文件包含许多命名元素,每个元素nodes下面都有几个:
<name search = "select ARG: write">
<version id = "1.0.0">
<value>myVal</value>
<method>myMethod</method>
</version>
</name>
<name search = "select ARG: bla">
<version id = "2.0.0">
<value>myVal</value>
<method>myMethod</method>
</version>
</name>
Run Code Online (Sandbox Code Playgroud)
我想搜索这个XML文件,如果这个名称搜索值以select ARG(在我的示例中第一个值是select ARG: write)开头,我想创建这个新的命名元素,但这次的值应该select ARG: write是selected ARG: write。这是我尝试过的:
from xml.dom import minidom
xamlfile = r'C:\file.xml'
newxamlfile = r'C:\new.xml'
dom = minidom.parse(xamlfile)
# Fetch the desired elements in the tree.
res = dom.getElementsByTagName('name')
# Loop through all.
for element in res:
search_name_value = element.getAttribute('search')
# Filter for the attribute and value.
if search_name_value.startswith('select ARG:'):
# In case of match, replace.
element.setAttribute('search_name', search_name_value.replace('select ARG:', 'selected ARG:'))
# Store the file.
with open(newxamlfile, 'w') as f:
f.write(dom.toxml())
Run Code Online (Sandbox Code Playgroud)
在这里,我替换了所需的字符串,但没有添加新的字符串,而是编辑所需的元素,而不是创建新的元素并将它们添加到文件中。
有什么建议如何做到这一点吗?
更新
这是我之前的文件:
<project version="4">
<name search="select ARG: write">
<version id="1.0.0">
<value>myVal</value>
<method>myMethod</method>
</version>
</name>
<name search="select ARG: bla">
<version id="2.0.0">
<value>myVal</value>
<method>myMethod</method>
</version>
</name>
</project>
Run Code Online (Sandbox Code Playgroud)
这就是我希望我的文件的样子:
<project version="4">
<name search="select ARG: write">
<version id="1.0.0">
<value>myVal</value>
<method>myMethod</method>
</version>
</name>
<name search="selected ARG: write">
<version id="1.0.0">
<value>myVal</value>
<method>myMethod</method>
</version>
</name>
<name search="select ARG: bla">
<version id="2.0.0">
<value>myVal</value>
<method>myMethod</method>
</version>
</name>
<name search="selected ARG: bla">
<version id="2.0.0">
<value>myVal</value>
<method>myMethod</method>
</version>
</name>
</project>
Run Code Online (Sandbox Code Playgroud)
编辑
根据@DirtyBit建议:
xmldoc = minidom.parse(xamlfile)
tags = xmldoc.getElementsByTagName("name")
for item in tags:
str = item.attributes["search"].value
if 'select ARG' in str:
item.attributes["search"].value = item.attributes["search"].value.replace('select ARG', 'selected ARG')
with open(xamlfile, "a+") as f:
xmldoc.writexml(f)
Run Code Online (Sandbox Code Playgroud)
这工作正常,但我有两个问题:
正如您所看到的,我添加了 if 语句,因为我只想在值为 with 时复制并创建新节点select ARG(并将其替换为selected ARG),而不复制不符合此条件的其他节点。
在新 XML 文件的中间有这样一行:
</element><?xml version="1.0" ?><element>
替换部分属性的解决方案(在用新要求更新之前):
\n\nimport xml.etree.ElementTree as ET\n\ntree = ET.parse(\'example.xml\')\n\nfor name in tree.getroot().iterfind(\'name\'):\n if name.attrib[\'search\'].startswith(\'select ARG\'):\n name.attrib[\'search\'] = name.attrib[\'search\'].replace(\n \'select ARG\', \'selected ARG\')\n\ntree.write(\'example.xml\')\nRun Code Online (Sandbox Code Playgroud)\n\n使用与上述解决方案相同的属性替换来附加新的相同块的解决方案:
\n\nimport xml.etree.ElementTree as ET\n\ntree = ET.parse(\'example.xml\')\n\nfor name in tree.getroot().iterfind(\'name\'):\n if name.attrib[\'search\'].startswith(\'select ARG\'):\n new = ET.Element(name.tag)\n new.attrib[\'search\'] = name.attrib[\'search\'].replace(\n \'select ARG\', \'selected ARG\')\n tree.getroot().append(new)\n for version in name.iterfind(\'version\'):\n new.append(version)\n\ntree.write(\'example.xml\')\nRun Code Online (Sandbox Code Playgroud)\n\n\n\n\n\nparse(source, parser=None)
\n\n
将外部 XML 部分加载到此元素树中。source 是文件名或文件对象。解析器是一个可选的解析器实例。如果未给出,则使用标准 XMLParser 解析器。返回节根元素。getroot()
\n\n
返回此树的根元素。iterfind(match)
\n\n
按标签名称或路径查找所有匹配的子元素。与 getroot().iterfind(match) 相同。返回一个可迭代的,产生\n 按文档顺序匹配的所有元素。attrib
\n\n
包含 element\xe2\x80\x99s 属性的字典。请注意,虽然 attrib 值始终是一个真正的可变 Python 字典,\n ElementTree 实现可以选择使用另一个内部\n 表示形式,并且仅在有人要求时才创建字典。\n 要利用此类实现,请使用尽可能使用下面的字典方法。class xml.etree.ElementTree.Element(tag, attrib={}, **extra)
\n\n
元素类。此类定义 Element 接口,并提供\n此接口的参考实现。元素名称、属性名称和属性值可以是字节字符串或 Unicode 字符串。tag 是元素名称。attrib 是一个可选字典,包含元素属性。extra 包含附加属性,以关键字参数形式给出。
\n\nappend(subelement)
\n\n
\n 将元素子元素添加到该元素内部子元素列表的末尾write(file,encoding="us-ascii", xml_declaration=None, default_namespace=None, method="xml")
\n
将元素树以 XML 形式写入\n 文件。file 是文件名或为写入而打开的文件对象。编码 [1] 是输出编码(默认为 US-ASCII)。\n xml_declaration 控制是否应将 XML 声明添加到\n 文件中。使用 False 表示从不,True 表示始终,None 表示仅在不使用时\n US-ASCII 或 UTF-8(默认值为 None)。default_namespace 设置默认 XML 命名空间(对于 \xe2\x80\x9cxmlns\xe2\x80\x9d)。方法是“xml”、“html”或\n“text”(默认为“xml”)。返回编码的字符串。