lxml - удаляет элемент, если у внуков есть текст - PullRequest
0 голосов
/ 18 февраля 2019

Поэтому я пытаюсь удалить элемент (данные), если его значение subElement имеет текст "1".Я провел некоторое исследование, в ходе которого выяснилось, как удалить значение элемента, но я понятия не имею, как удалить прародителя элемента.Я знаю, что могу найти текст, выполнив поиск таким образом, а затем удалить элемент, но это все, что я смог найти.

e = root.xpath('.//value[text()="1"]')
e.getParent().remove

Мой XML-документ выглядит так:

<root>
  <Data>
    <FirstName>Name</FirstName>
    <EMail>email@email.com</EMail>
    <Number>123</Number>
    <delete>
      <value>0</value>
    </delete>
  </Data>
  <Data>
    <FirstName>Name</FirstName>
    <EMail>some@email.com</EMail>
    <delete>
      <value>1</value>
    </delete>
    <Number>456</Number>
  </Data>
</root>

Ожидаемый результат:

<root>
  <Data>
    <FirstName>Name</FirstName>
    <EMail>email@email.com</EMail>
    <Number>123</Number>
    <delete>
    <value>0</value>
    </delete>
  </Data>
</root>

В основном я хочу удалить данные элемента, если значение элемента содержит определенный текст.

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Если вы хотите удалить элемент, вам нужен его родитель.В этом случае родительский элемент Data равен root (который также является корневым элементом).

Вместо выбора value используйте предикат для выбора Data и удалите его из root вот так ...

Python

from lxml import etree

tree = etree.parse("test.xml")
root = tree.getroot()

for data in tree.xpath("./Data[delete/value='1']"):
    root.remove(data)

print(etree.tostring(tree, pretty_print=True).decode())

Вывод на печать

<root>
  <Data>
    <FirstName>Name</FirstName>
    <EMail>email@email.com</EMail>
    <Number>123</Number>
    <delete>
      <value>0</value>
    </delete>
  </Data>
</root>

Если мне нужно удалить элемент, я почти никогда не использую getparent();Я выбираю родителя специально.Если мне нужно выполнить более сложные преобразования, я использую XSLT, как предложено Parfait.

0 голосов
/ 18 февраля 2019

Рассмотрим XSLT (родственный XPath), язык специального назначения, предназначенный для преобразования файлов XML в другой XML.Модуль Python lxml в дополнение к запуску XPath 1.0 также может запускать сценарии XSLT 1.0.

XSLT (сохранить как файл .xsl, специальный файл .xml)

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output version="1.0" encoding="UTF-8" indent="yes" />
  <xsl:strip-space elements="*"/>

  <!-- Identity Transform -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- Removes entire Data node with delete child value equal to 1 -->
  <xsl:template match="Data[delete/value='1']"/>

</xsl:transform>

Python (без for циклов или if логики)

import lxml.etree as et

# LOAD XML AND XSL
xml = et.parse('input.xml')
xsl = et.parse('xslt_script.xsl')

# TRANSFORM INPUT 
transform = et.XSLT(xsl)    
result = transform(xml)

# SAVE TO FILE
with open('output.xml', 'wb') as f:
    f.write(result)
...