2016-05-04 1 views
1

Я использую библиотеку lxml и Python 2.7 для разбора XML-файлов. Мне нужно определить, есть ли элементы-братья, у которых нет текста между ними. Например, в следующем XML часть:Определить, является ли непосредственный родственник элемента текстовым или другим элементом в lxml

<cross-ref> [t1] </cross-ref> ***some text*** <cross-ref> [t2] </cross-ref> 
<cross-ref> [t3] </cross-ref><cross-ref> [t4] </cross-ref> 

говоря, что я обнаруживаю все элементы с кросс-реф теги, мне нужен способ, который только определяет кросс-реф элементы на второй линии, второй элемент приходит после того, как первый с не текст между ними. Так что я думаю, что-то как folloing цикл необходима, но очевидно, этот код печатает как [t1] и [t3]

for c in cross_refs: 
    # detect ***some text*** or do something else here 
    if c.getnext().tag == "cross-ref": 
    print c.text 

мне нужно изменить его таким образом, выход будет только [t3].

ответ

2

Тройных вложенные if s в вашем ответе также может быть выражен в XPath следующим образом:

following-sibling::node()[1][self::cross-ref] 

Короче говоря, XPath возвращает ближайший следующие двойники узла только если это cross-ref элемент. Обратите внимание, что узел здесь означает либо текстовый узел, либо узел элемента. XPath можно использовать следующим образом:

for c in cross_refs: 
    if c.xpath('boolean(following-sibling::node()[1][self::cross-ref])'): 
     print c.text 

Или вы можете получить только cross-ref элементы, которые соответствуют этим критериям, в первую очередь, если вы хотите:

cross_refs = tree.xpath('//cross-ref[following-sibling::node()[1][self::cross-ref]]') 
for c in cross_refs: 
    print c.text 
+0

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

+1

Возможно, я был неясен. Я имею в виду, что следующие биты «не различают текст и элемент»: 'next-sibling :: node() [1]', но затем следующие биты фильтруют далее только элемент 'cross-ref':' [self :: кросс-ссылок] '. Таким образом, все выражение возвращает следующий элемент 'cross-ref', если он непосредственно после текущего' cross-ref', который затем может быть использован для решения проблемы, о которой вы упоминали. – har07

+1

@AliGH: используя XPath от har07, вы можете найти желаемый элементы без хвостов, используя '[elt.text для elt в tree.xpath ('// cross-ref [next-sibling :: * [1] [self :: cross-ref]]', если elt.tail is None] '. – unutbu

0

Я решил проблему с использованием свойства tail. Когда c.tail - None, я могу сказать, что к элементам прикреплены без текста между ними. Код выглядит так:

for c in cross_refs: 
    if c.getnext() != None: 
     if c.getnext().tag == c.tag: 
      if c.tail == None: 
       print c.text 

 Смежные вопросы

  • Нет связанных вопросов^_^