XPath: выберите тег с пустым значением - PullRequest
9 голосов
/ 31 декабря 2011

Как найти в XPath 1.0 все строки с пустыми col name="POW"?

<row>
<col name="WOJ">02</col>
<col name="POW"/>
<col name="GMI"/>
<col name="RODZ"/>
<col name="NAZWA">DOLNOŚLĄSKIE</col>
<col name="NAZDOD">województwo</col>
<col name="STAN_NA">2011-01-01</col>
</row>

Я пробовал много решений. Несколько раз в расширении Firefox выбор XPath Checker был в порядке, но lxml.xpath() говорит, что выражение недопустимо или просто не возвращает строк.

Мой код Python:

from lxml import html
f = open('TERC.xml', 'r')
page = html.fromstring(f.read())
for r in page.xpath("//row[col[@name = 'POW' and not(text())]]"):
    print r.text_content()
    print "-------------------------"

Ответы [ 3 ]

8 голосов
/ 31 декабря 2011

Как я могу найти в XPath 1.0 все строки с пустыми col name="POW"?

Существует много возможных определений «пустых», и для каждого из них есть разные XPathвыражение, выбирающее «пустые» элементы.

Разумное определение для пустого элемента: элемент, не имеющий дочерних элементов и дочерних элементов текстового узла, или элемент, имеющий единственный дочерний элемент текстового узла, строка которогозначение содержит только пробельные символы.

Это выражение XPath :

//row[col[@name = 'POW']
                    [not(*)]
                       [not(normalize-space())]
      ]

выбирает все элементы row в документе XML, которые имеют дочерний элемент col,который имеет атрибут name со строковым значением "POW" и у которого нет дочерних элементов и строковое значение которого состоит либо полностью из пробельных символов, либо является пустой строкой.

In case by "пустое «вы понимаете», что у вас вообще нет дочерних элементов , что означает отсутствие дочерних элементов и дочерних узлов PI и дочерних узлов комментариев, затем используйте:

//row[col[@name = 'POW']
                    [not(node())]
      ]
3 голосов
/ 31 декабря 2011
//row[col[@name='POW' and not(normalize-space())]]

Чтобы столбец POW также не имел дочерних элементов (даже если они не содержат текста), добавьте дополнительный фильтр предикатов:

//row[col[@name='POW' and not(normalize-space()) and not(*)]]
1 голос
/ 31 декабря 2011

Используйте это:

//row[col[@name = 'POW' and not(text())]]
...