Фильтрация XML-файла для удаления строк с определенным текстом в них? - PullRequest
2 голосов
/ 04 июля 2011

Например, предположим, у меня есть:

<div class="info"><p><b>Orange</b>, <b>One</b>, ...
<div class="info"><p><b>Blue</b>, <b>Two</b>, ...
<div class="info"><p><b>Red</b>, <b>Three</b>, ...
<div class="info"><p><b>Yellow</b>, <b>Four</b>, ...

И я хотел бы удалить все строки, содержащие слова, из списка, поэтому я буду использовать xpath только для тех строк, которые соответствуют моим критериям. Например, я мог бы использовать список как ['Orange', 'Red'], чтобы отметить нежелательные строки, поэтому в приведенном выше примере я бы хотел использовать только строки 2 и 4 для дальнейшей обработки.

Как я могу это сделать?

Ответы [ 2 ]

1 голос
/ 04 июля 2011
* +1000 * Используйте
//div
  [not(p/b[contains('|Orange|Red|', 
                    concat('|', ., '|')
                   )
          ]
       )
  ]

Это выбирает любые элементы div в документе XML, так что у него нет дочернего элемента p, чье значение дочернего элемента b является одной из строк в списке строк, разделенных по конвейеру, для использования в качестве фильтров.

Этот подход обеспечивает расширяемость, просто добавляя новые значения фильтра в список, разделенный конвейерами, без изменения чего-либо еще в выражении XPath.

Примечание : Когда структура XML-документа известна статически, всегда избегайте использования псевдооператора XPath //, поскольку это приводит к значительной неэффективности (замедлению).

0 голосов
/ 04 июля 2011
import lxml.html as lh

# http://lxml.de/xpathxslt.html
# http://exslt.org/regexp/functions/match/index.html
content='''\
<table>
<div class="info"><p><b>Orange</b>, <b>One</b></p></div>
<div class="info"><p><b>Blue</b>, <b>Two</b></p></div>
<div class="info"><p><b>Red</b>, <b>Three</b></p></div>
<div class="info"><p><b>Yellow</b>, <b>Four</b></p></div>
</table>
'''
NS = 'http://exslt.org/regular-expressions'
tree = lh.fromstring(content)
exclude=['Orange','Red']
for elt in tree.xpath(
    "//div[not(re:test(p/b[1]/text(), '{0}'))]".format('|'.join(exclude)),
    namespaces={'re': NS}):
    print(lh.tostring(elt))
    print('-'*80)

выходы

<div class="info"><p><b>Blue</b>, <b>Two</b></p></div>

--------------------------------------------------------------------------------
<div class="info"><p><b>Yellow</b>, <b>Four</b></p></div>

--------------------------------------------------------------------------------
...