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

时间:2016-01-27 05:57:50

标签: python xml jenkins

例如:

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

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

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

2 个答案:

答案 0 :(得分:0)

最简单的尝试可能正在使用lxml.etree并按xpath抓取节点(例如此处为//hudson.model.StringParameterDefinition/defaultValue),如下所示进行更改并正确更改 -

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)

输出 -

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

我将介绍ElementTree和Minidom。我不熟悉元素

对于这些例子,我们让

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

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

对于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是这里最难使用的,因为它没有理解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)

要遍历所有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

在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

最后,要将文档转回字符串吗

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