如何使用python基于xml中的兄弟标记文本值修改标记文本值?

时间:2022-11-26 23:44:36

For Eg:

<parameterDefinitions>
        <hudson.model.StringParameterDefinition>
          <name>name</name>
          <description></description>
          <defaultValue>abc</defaultValue>
        </hudson.model.StringParameterDefinition>
        <hudson.model.BooleanParameterDefinition>
          <name>branch</name>
          <description></description>
          <defaultValue>true</defaultValue>
        </hudson.model.BooleanParameterDefinition>
</parameterDefinitions>

Above given is the small part of XML file which am getting from the Jenkins server. I need to modify the default value(abc and true for the above eg) of the parameters based on its respective name(name and branch).

上面给出的是从Jenkins服务器获取的XML文件的一小部分。我需要根据各自的名称(名称和分支)修改参数的默认值(例如上面的abc和true)。

Have read about MiniDom, Element and ElementTree but couldn't figure out the exact api. Can anyone help me out with this. Thanks in advance.

已阅读有关MiniDom,Element和ElementTree但无法弄清楚确切的api。任何人都可以帮我解决这个问题。提前致谢。

2 个解决方案

#1


0  

I'll cover ElementTree and Minidom. I am unfamiliar with Element.

我将介绍ElementTree和Minidom。我对Element不熟悉。

For these examples, we let

对于这些例子,我们让

raw = """
    <parameterDefinitions>
        <hudson.model.StringParameterDefinition>
            <name>name</name>
            <description></description>
            <defaultValue>abc</defaultValue>
        </hudson.model.StringParameterDefinition>
        <hudson.model.BooleanParameterDefinition>
            <name>branch</name>
            <description></description>
            <defaultValue>true</defaultValue>
        </hudson.model.BooleanParameterDefinition>
    </parameterDefinitions>
""""

I'll demonstrate the api by changing the first abc default value to the value of the name element. You can modify these to suit the change however you need to make it.

我将通过将第一个abc默认值更改为name元素的值来演示api。您可以修改这些以适应更改,但您需要进行更改。

For ElementTree, we do

对于ElementTree,我们这样做

import xml.etree.ElementTree as ET
root = ET.fromstring(raw)
node = root.find(".//hudson.model.StringParameterDefinition")
node.find(".//defaultValue").text = node.find(".//name").text

MiniDom is the most difficult to use here, as it doesn't have the advantage of understanding xpath. However, to do the same, with the value of raw as above,

MiniDom是这里最难使用的,因为它没有理解xpath的优势。但是,要做同样的事情,使用如上所述的raw值,

import xml.dom.minidom as MD
root = MD.parseString(raw)
node = root.childNodes[0].getElementsByTagName("hudson.model.StringParameterDefinition")[0]
defaultValue = node.getElementsByTagName("defaultValue")[0]
defaultValue.childNodes[0].replaceWholeText(node.getElementsByTagName("name")[0].childNodes[0].nodeValue)

To loop over all the xParameterDefinition elements, in ElementTree, use

要遍历所有xParameterDefinition元素,请在ElementTree中使用

for x in ET.findall("./*"):
    # first time will be hudson.model.StringParameterDefinition
    # second time will be hudson.model.BooleanParameterDefinition
    # put loop body here

in Minidom, use

在Minidom,使用

for x in root.childNodes[0].childNodes:
    if isinstance(x,MD.Element): # do this to avoid text nodes (ie newlines)
        # put loop body here

Finally, to turn the documents back into a string do

最后,将文档转回字符串做

ET.tostring(root) # ElementTree
root.toxml() # minidom

#2


0  

Simplest try may be using lxml.etree and grabbing the node by xpath (i.e. //hudson.model.StringParameterDefinition/defaultValue here) to be changed as below and changing properly-

最简单的尝试可能是使用lxml.etree并通过xpath抓取节点(即//hudson.model.StringParameterDefinition/defaultValue here),如下所示进行更改并正确更改 -

from lxml import etree as et

data = """<parameterDefinitions>
        <hudson.model.StringParameterDefinition>
          <name>name</name>
          <description></description>
          <defaultValue>abc</defaultValue>
        </hudson.model.StringParameterDefinition>
        <hudson.model.BooleanParameterDefinition>
          <name>branch</name>
          <description></description>
          <defaultValue>true</defaultValue>
        </hudson.model.BooleanParameterDefinition>
</parameterDefinitions>"""

tree = et.fromstring(data)
w = tree.xpath("//hudson.model.StringParameterDefinition/defaultValue")
w[0].text = "changed"# here w is a list
print et.tostring(tree,pretty_print=True)

Output-

<parameterDefinitions>
        <hudson.model.StringParameterDefinition>
          <name>name</name>
          <description/>
          <defaultValue>changed</defaultValue>
        </hudson.model.StringParameterDefinition>
        <hudson.model.BooleanParameterDefinition>
          <name>branch</name>
          <description/>
          <defaultValue>true</defaultValue>
        </hudson.model.BooleanParameterDefinition>
</parameterDefinitions>

#1


0  

I'll cover ElementTree and Minidom. I am unfamiliar with Element.

我将介绍ElementTree和Minidom。我对Element不熟悉。

For these examples, we let

对于这些例子,我们让

raw = """
    <parameterDefinitions>
        <hudson.model.StringParameterDefinition>
            <name>name</name>
            <description></description>
            <defaultValue>abc</defaultValue>
        </hudson.model.StringParameterDefinition>
        <hudson.model.BooleanParameterDefinition>
            <name>branch</name>
            <description></description>
            <defaultValue>true</defaultValue>
        </hudson.model.BooleanParameterDefinition>
    </parameterDefinitions>
""""

I'll demonstrate the api by changing the first abc default value to the value of the name element. You can modify these to suit the change however you need to make it.

我将通过将第一个abc默认值更改为name元素的值来演示api。您可以修改这些以适应更改,但您需要进行更改。

For ElementTree, we do

对于ElementTree,我们这样做

import xml.etree.ElementTree as ET
root = ET.fromstring(raw)
node = root.find(".//hudson.model.StringParameterDefinition")
node.find(".//defaultValue").text = node.find(".//name").text

MiniDom is the most difficult to use here, as it doesn't have the advantage of understanding xpath. However, to do the same, with the value of raw as above,

MiniDom是这里最难使用的,因为它没有理解xpath的优势。但是,要做同样的事情,使用如上所述的raw值,

import xml.dom.minidom as MD
root = MD.parseString(raw)
node = root.childNodes[0].getElementsByTagName("hudson.model.StringParameterDefinition")[0]
defaultValue = node.getElementsByTagName("defaultValue")[0]
defaultValue.childNodes[0].replaceWholeText(node.getElementsByTagName("name")[0].childNodes[0].nodeValue)

To loop over all the xParameterDefinition elements, in ElementTree, use

要遍历所有xParameterDefinition元素,请在ElementTree中使用

for x in ET.findall("./*"):
    # first time will be hudson.model.StringParameterDefinition
    # second time will be hudson.model.BooleanParameterDefinition
    # put loop body here

in Minidom, use

在Minidom,使用

for x in root.childNodes[0].childNodes:
    if isinstance(x,MD.Element): # do this to avoid text nodes (ie newlines)
        # put loop body here

Finally, to turn the documents back into a string do

最后,将文档转回字符串做

ET.tostring(root) # ElementTree
root.toxml() # minidom

#2


0  

Simplest try may be using lxml.etree and grabbing the node by xpath (i.e. //hudson.model.StringParameterDefinition/defaultValue here) to be changed as below and changing properly-

最简单的尝试可能是使用lxml.etree并通过xpath抓取节点(即//hudson.model.StringParameterDefinition/defaultValue here),如下所示进行更改并正确更改 -

from lxml import etree as et

data = """<parameterDefinitions>
        <hudson.model.StringParameterDefinition>
          <name>name</name>
          <description></description>
          <defaultValue>abc</defaultValue>
        </hudson.model.StringParameterDefinition>
        <hudson.model.BooleanParameterDefinition>
          <name>branch</name>
          <description></description>
          <defaultValue>true</defaultValue>
        </hudson.model.BooleanParameterDefinition>
</parameterDefinitions>"""

tree = et.fromstring(data)
w = tree.xpath("//hudson.model.StringParameterDefinition/defaultValue")
w[0].text = "changed"# here w is a list
print et.tostring(tree,pretty_print=True)

Output-

<parameterDefinitions>
        <hudson.model.StringParameterDefinition>
          <name>name</name>
          <description/>
          <defaultValue>changed</defaultValue>
        </hudson.model.StringParameterDefinition>
        <hudson.model.BooleanParameterDefinition>
          <name>branch</name>
          <description/>
          <defaultValue>true</defaultValue>
        </hudson.model.BooleanParameterDefinition>
</parameterDefinitions>