XPath: выберите тег с пустым значением

как я могу найти в 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 ответов


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

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

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

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

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

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

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

//row[col[@name = 'POW']
                    [not(node())]
      ]

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

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

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

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

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