python - Python: how to edit element of XML file?
问题描述
I have an XML
file, This file includes many named elements, each element has several nodes
under it:
<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>
I want to search this XML
file and in case this name search value starts with select ARG
(in my example this the first value is select ARG: write
) i want to create this new named element but this time the value that was select ARG: write
should be selected ARG: write
. This is what I have tried:
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())
Here, I have replaced the desired string and not added the new one, editing the elements that I want instead of creating new ones and adding them to the file.
Any suggestions how to do that?
UPDATE
This is my file before:
<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>
This is how i want my file will be:
<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>
EDIT
According @DirtyBit
suggestion:
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)
This works fine but i have 2 issues:
As you can see i added if statement because i want to duplicate and create new node only in the value is with
select ARG
(and replace it withselected ARG
) and not duplicate the others that did not mach this conditions.At he middle of the new XML file i have this line:
</element><?xml version="1.0" ?><element>
解决方案
替换部分属性的解决方案(在使用新要求更新之前):
import xml.etree.ElementTree as ET
tree = ET.parse('example.xml')
for name in tree.getroot().iterfind('name'):
if name.attrib['search'].startswith('select ARG'):
name.attrib['search'] = name.attrib['search'].replace(
'select ARG', 'selected ARG')
tree.write('example.xml')
在属性上添加与上述解决方案相同的替换属性的新相同块的解决方案:
import xml.etree.ElementTree as ET
tree = ET.parse('example.xml')
for name in tree.getroot().iterfind('name'):
if name.attrib['search'].startswith('select ARG'):
new = ET.Element(name.tag)
new.attrib['search'] = name.attrib['search'].replace(
'select ARG', 'selected ARG')
tree.getroot().append(new)
for version in name.iterfind('version'):
new.append(version)
tree.write('example.xml')
parse(source, parser=None)
将外部 XML 部分加载到此元素树中。source 是文件名或文件对象。parser 是一个可选的解析器实例。如果未给出,则使用标准 XMLParser 解析器。返回节根元素。getroot()
返回此树的根元素。iterfind(match)
按标签名称或路径查找所有匹配的子元素。与 getroot().iterfind(match) 相同。返回一个iterable,产生文档顺序中的所有匹配元素。attrib
包含元素属性的字典。请注意,虽然 attrib 值始终是一个真正的可变 Python 字典,但 ElementTree 实现可能会选择使用另一种内部表示,并且仅在有人要求时才创建字典。要利用此类实现,请尽可能使用以下字典方法。class xml.etree.ElementTree.Element(tag, attrib={}, **extra)
元素类。该类定义了 Element 接口,并提供了该接口的参考实现。元素名称、属性名称和属性值可以是字节字符串或 Unicode 字符串。tag 是元素名称。attrib 是一个可选字典,包含元素属性。extra 包含附加属性,作为关键字参数给出。
append(subelement)
将元素子元素添加到此元素的末尾 子元素的内部列表write(file, encoding="us-ascii", xml_declaration=None, default_namespace=None, method="xml")
将元素树以 XML 格式写入文件。file 是文件名,或为写入而打开的文件对象。encoding [1] 是输出编码(默认为 US-ASCII)。xml_declaration 控制是否应将 XML 声明添加到文件中。使用 False 表示从不,True 表示永远,None 仅在不是 US-ASCII 或 UTF-8 时使用(默认为 None)。default_namespace 设置默认的 XML 命名空间(用于“xmlns”)。方法是“xml”、“html”或“text”(默认为“xml”)。返回一个编码的字符串。
推荐阅读
- composer-php - Symfony 4 和 PHP 7.3 我得到 Composer 更新错误
- ansible - 为什么一个特殊的ansible变量是未定义的?
- javascript - 当我想在下一个最小空白中添加比前一个最大空白更多的价值时,如何解决发生的计费层问题?
- asp.net-mvc - ASP.NET MVC Razor 在用户编辑输入文件时捕获 textchange 事件
- video - 如何为基于 Flutter 构建的应用录制的视频添加时间戳
- c# - 实体框架 - 外键对象未映射到抽象类
- spring-boot - 从单个 SQSListener 监听多个 AWS SQS
- flutter - 使用 Flutter 查询 Firestore 中的子集合
- reactjs - 我怎么知道渲染原因是在反应钩子函数中改变了属性还是改变了状态?
- microsoft-graph-api - Places Room List API 返回缓存数据