Python:如何编辑 XML 文件的元素? [英] Python: how to edit element of XML file?

查看:25
本文介绍了Python:如何编辑 XML 文件的元素?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个XML文件,这个文件包含很多命名元素,每个元素下面有几个nodes:

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>

我想搜索此 XML 文件,以防此名称搜索值以 select ARG 开头(在我的示例中,第一个值为 select ARG:write) 我想创建这个新的命名元素,但是这次 select ARG: write 的值应该是 selected ARG: write.这是我尝试过的:

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?

更新

这是我之前的文件:

<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>

编辑

根据@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)

这很好用,但我有两个问题:

This works fine but i have 2 issues:

  1. 如您所见,我添加了 if 语句,因为我想复制并仅在值中创建新节点 select ARG (并将其替换为 selected ARG) 并且不复制不符合此条件的其他代码.

  1. 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 with selected ARG) and not duplicate the others that did not mach this conditions.

在新 XML 文件的中间,我有这一行:

At he middle of the new XML file i have this line:

</element><?xml version="1.0" ?><element>

推荐答案

替换部分属性的解决方案(在使用新要求更新之前):

Solution to replace part of an attribute (before update with new requirements):

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')

添加具有与上述解决方案相同的属性替换的新相同块的解决方案:

Solution to append new identical blocks with same replace on attribute as the above solution:

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')

来自 ElementTree 文档:

parse(source, parser=None)
将外部 XML 部分加载到此元素树中.source 是文件名或文件对象.解析器是一个可选的解析器实例.如果没有给出,标准的 XMLParser 解析器用来.返回部分根元素.

parse(source, parser=None)
Loads an external XML section into this element tree. source is a file name or file object. parser is an optional parser instance. If not given, the standard XMLParser parser is used. Returns the section root element.

getroot()
返回这棵树的根元素.

getroot()
Returns the root element for this tree.

iterfind(match)
按标签名称或路径查找所有匹配的子元素.与 getroot().iterfind(match) 相同.返回一个可迭代的产量文档顺序中的所有匹配元素.

iterfind(match)
Finds all matching subelements, by tag name or path. Same as getroot().iterfind(match). Returns an iterable yielding all matching elements in document order.

attrib
包含元素属性的字典.请注意,虽然 attrib 值始终是一个真正的可变 Python 字典,但ElementTree 实现可以选择使用另一个内部表示,并仅在有人要求时才创建字典.要利用此类实现,请使用字典方法尽可能低于.

attrib
A dictionary containing the element’s attributes. Note that while the attrib value is always a real mutable Python dictionary, an ElementTree implementation may choose to use another internal representation, and create the dictionary only if someone asks for it. To take advantage of such implementations, use the dictionary methods below whenever possible.

class xml.etree.ElementTree.Element(tag, attrib={}, **extra)
元素类.该类定义了 Element 接口,并提供此接口的参考实现.

class xml.etree.ElementTree.Element(tag, attrib={}, **extra)
Element class. This class defines the Element interface, and provides a reference implementation of this interface.

元素名称、属性名称和属性值可以是字节串或 Unicode 字符串.tag 是元素名称.属性是一个可选字典,包含元素属性.额外包含附加属性,作为关键字参数给出.

The element name, attribute names, and attribute values can be either bytestrings or Unicode strings. tag is the element name. attrib is an optional dictionary, containing element attributes. extra contains additional attributes, given as keyword arguments.

追加(子元素)
将元素子元素添加到此元素内部子元素列表的末尾

append(subelement)
Adds the element subelement to the end of this elements internal list of subelements

write(file, encoding="us-ascii", xml_declaration=None, default_namespace=None, method="xml")
将元素树写入文件,作为 XML.file 是一个文件名,或者是一个打开的文件对象写作.encoding [1] 是输出编码(默认为 US-ASCII).xml_declaration 控制是否应将 XML 声明添加到文件.从不使用 False,始终使用 True,仅在没有时使用 NoneUS-ASCII 或 UTF-8(默认为无).default_namespace 设置默认 XML 命名空间(用于xmlns").方法是xml"、html"或文本"(默认为xml").返回一个编码字符串.

write(file, encoding="us-ascii", xml_declaration=None, default_namespace=None, method="xml")
Writes the element tree to a file, as XML. file is a file name, or a file object opened for writing. encoding [1] is the output encoding (default is US-ASCII). xml_declaration controls if an XML declaration should be added to the file. Use False for never, True for always, None for only if not US-ASCII or UTF-8 (default is None). default_namespace sets the default XML namespace (for "xmlns"). method is either "xml", "html" or "text" (default is "xml"). Returns an encoded string.

这篇关于Python:如何编辑 XML 文件的元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆