Python 2.7:使用 lxml 查找和更新 xml

Python 2.7 : Find and update xml using lxml

我有以下 xml :

<?xml version='1.0' encoding='UTF-8'?>
<parserResult>
  <ParsedData>
    <Signals>
      <Signal>
        <Name name="asc_epsWarn_mu8"/>
        <Aufloesung ist="" soll="2^-0"/>
        <Min-wert ist="" soll="0"/>
        <Max-wert ist="" soll="1"/>
        <ErrorClass error="Signal does not exist in A2L file"/>
        <Bewertung evaluation="FAIL"/>
      </Signal>
    </Signals>
  </ParsedData>
 </parserResult>

我想搜索信号名称并更新 Aufloseung、Min-wert 和 Max-wert 元素。 我从外部源获取 <Signals> 元素,然后我能够在 xml.

中找到信号
signal_name = asc_epsWarn_mu8

 signal = signals.xpath("//Signal/Name[@name='%s']" % signal_name)

现在如何更新此信号的 Aufloseung、Min-wert 和 Max-wert 元素?我想要如下输出:

<?xml version='1.0' encoding='UTF-8'?>
<parserResult>
  <ParsedData>
    <Signals>
      <Signal>
        <Name name="asc_epsWarn_mu8"/>
        <Aufloesung ist="23" soll="2^-0"/>
        <Min-wert ist="23" soll="0"/>
        <Max-wert ist="23" soll="1"/>
        <ErrorClass error="Signal does not exist in A2L file"/>
        <Bewertung evaluation="FAIL"/>
      </Signal>
    </Signals>
  </ParsedData>
 </parserResult>

更新: 我尝试了以下代码,但它没有更新我的值:

min_wert = signal[0].xpath('//Min-wert')
max_wert = signal[0].xpath('//Max-wert')

min_wert[0].set('ist','23')
max_wert[0].set('ist','23')

获得信号元素后,您可以执行第二个 xpath 以获取 Min-wert 和 Max-wert 元素:

min_wert = signal[0].xpath('//Min-wert')[0]
max_wert = signal[0].xpath('//Max-wert')[0]

然后,您可以设置属性:

min_wert.set('ist','23')
max_wert.set('ist','23')

第一个问题是:

signal = signals.xpath("//Signal/Name[@name='%s']" % signal_name)

您打算 select Signal,但您确实 select Name

改为:

signal = signals.xpath("//Signal[Name/@name='%s']" % signal_name)

此外,当您执行此操作时(特别是 xpath 中的 //):

min_wert = signal[0].xpath('//Min-wert')
max_wert = signal[0].xpath('//Max-wert')

XPath 正在整个树中搜索第一个 Min-wertMax-wert

要搜索当前上下文(当前 Signal),请使用 Min-wert./Min-wert.//Min-wert。由于 Min-wertSignal 的直系子代,因此您只需要 Min-wert...

min_wert = signal[0].xpath('Min-wert')
max_wert = signal[0].xpath('Max-wert')

另一种替代方法是 select "Aufloesung"、"Min-wert" 和 "Max-wert" 使用单个 xpath。

完整示例...

XML输入(input.xml;又加了一个Signal表示更新正确)

<parserResult>
    <ParsedData>
        <Signals>
            <Signal>
                <Name name="ignore me"/>
                <Aufloesung ist="" soll="2^-0"/>
                <Min-wert ist="" soll="0"/>
                <Max-wert ist="" soll="1"/>
            </Signal>
            <Signal>
                <Name name="asc_epsWarn_mu8"/>
                <Aufloesung ist="" soll="2^-0"/>
                <Min-wert ist="" soll="0"/>
                <Max-wert ist="" soll="1"/>
                <ErrorClass error="Signal does not exist in A2L file"/>
                <Bewertung evaluation="FAIL"/>
            </Signal>
        </Signals>
    </ParsedData>
</parserResult>

Python

from lxml import etree

tree = etree.parse("input.xml")

signal_name = "asc_epsWarn_mu8"

signal = tree.xpath("//Signal[Name/@name='%s']" % signal_name)[0]

for elem in signal.xpath("*[self::Aufloesung or self::Min-wert or self::Max-wert]"):
    elem.set("ist", "23")

etree.dump(tree.getroot())

XML 输出(转储到控制台)

<parserResult>
    <ParsedData>
        <Signals>
            <Signal>
                <Name name="ignore me"/>
                <Aufloesung ist="" soll="2^-0"/>
                <Min-wert ist="" soll="0"/>
                <Max-wert ist="" soll="1"/>
            </Signal>
            <Signal>
                <Name name="asc_epsWarn_mu8"/>
                <Aufloesung ist="23" soll="2^-0"/>
                <Min-wert ist="23" soll="0"/>
                <Max-wert ist="23" soll="1"/>
                <ErrorClass error="Signal does not exist in A2L file"/>
                <Bewertung evaluation="FAIL"/>
            </Signal>
        </Signals>
    </ParsedData>
</parserResult>