简体   繁体   中英

Python 2.7 : Find and update xml using lxml

I have below 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>

I want to search for signal name and update the Aufloseung, Min-wert and Max-wert elements. I am getting the <Signals> element from external source and then I am able find the signal in xml.

signal_name = asc_epsWarn_mu8

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

Now How can I update Aufloseung, Min-wert and Max-wert elements of this signal? I want an output like below :

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

Update : I tried below code but it doesnt update my values :

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

Once you have the signal element, you can do a second xpath to get the Min-wert and Max-wert elements:

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

Then, you can set the attributes:

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

The first issue is with this:

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

You're intending to select Signal , but you're really selecting Name .

Change it to:

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

Also, when you do this (specifically the // in the xpath):

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

the XPath is searching the entire tree for the first Min-wert and Max-wert .

To search the current context (the current Signal ) use either Min-wert , ./Min-wert , or .//Min-wert . Since Min-wert is a direct child of Signal , just Min-wert is all you need...

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

Another alternative is to select "Aufloesung", "Min-wert", and "Max-wert" with a single xpath.

Full example...

XML Input (input.xml; added another Signal to show that the correct one is updated)

<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 Output (dumped to console)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM