Python 2.7: поиск и обновление xml с использованием lxml - PullRequest
0 голосов
/ 03 мая 2019

у меня ниже 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')

Ответы [ 2 ]

1 голос
/ 03 мая 2019

Первая проблема связана с этим:

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

Вы собираетесь выбрать Signal, но вы действительно выбираете 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-wert и Max-wert.

Для поиска в текущем контексте (текущем Signal) используйте Min-wert, ./Min-wert или .//Min-wert.Поскольку Min-wert является прямым потомком Signal, просто Min-wert - это все, что вам нужно ...

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

Другой вариант - выбрать "Aufloesung", "Min-wert" и "Max-wert "с одним xpath.

Полный пример ...

XML Input (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>
1 голос
/ 03 мая 2019

Когда у вас есть элемент сигнала, вы можете выполнить второй 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')
...