2016-05-06 1 views
2

У меня есть этот упрощенный XML с большим количеством A элементов:питон XPath: Сравнение даты

<root>  
    <A class="a" version="7"> 
     <details> 
      <dates> 
      <status date="2013-04-29T04:16:49.792-04:00">ACCEPTED</status> 
      <status date="2013-08-12T04:08:23.773-04:00">ACCEPTED</status> 
      </dates> 
     </details> 
    </A> 
    <A class="a" version="7"> 
    ... 
</root> 

Как я могу получить только те A элементы, дата последнего состояния больше определенной временной точке, используя LXML XPath ,

То, что я сделал до сих пор:

from lxml import etree 
tree = etree.parse("./my.xml") 
root = tree.getroot() 
res = root.xpath("A[./details/dates/status[last()]/@date > '2013-08-12T00:00:0.000-04:00' ]"); 

Но проблема с этим кодом является то, что сравнение всегда возвращает ложной по какой-то причине, так что resвсегда пуст.

Любая помощь или совет приветствуются.

ответ

2

Вам нужно будет перевести и сравнить, как номер:

In [24]: x = """<root> 
    ....:  <A class="a" version="7"> 
    ....:  <details> 
    ....:   <dates> 
    ....:    <status date="2013-04-29T04:16:49.792-04:00">ACCEPTED</status> 
    ....:    <status date="2013-08-12T04:08:23.773-04:00">ACCEPTED</status> 
    ....:   </dates> 
    ....:  </details> 
    ....:  </A> 
    ....:  <A class="a" version="7"> 
    ....: </root>""" 

In [25]: from lxml import html 


In [26]: xml = html.fromstring(x) 


In [27]: print(xml.xpath("a[translate(./details/dates/status[last()]/@date,'-:T.','') > '201308120000000000400']")) 
[<Element a at 0x7fdb45bc8aa0>] 

это будет хорошо, чтобы сравнить, как только вы всегда сравнение дат с тем же смещением и у вас есть то же количество цифр, что и ваши даты в формате iso8601 с форматом yyyy-mm-dd, поэтому можно с уверенностью сравнивать, если у вас есть разные смещения или цифры цифр, тогда вам придется сравнивать их как объекты datetime ,

+0

Я боюсь, что это не сработает, как ожидалось, из-за отсутствия числа в xpath/lxml (очка с плавающей запятой). Это будет «2.01308120408e + 20.». Поэтому он должен быть более сложным xapth (например, сравнивать дату 'substring-before (..., 'T')' и время. –

1

Нет типа даты в xpath 1.0, и вы не можете сравнивать строки в xpath 1.0 с операторами, отличными от = и !=. У вас есть пакет, который поддерживает часть xpath 2 в python, но я никогда не пробовал (см. here). Это может быть способ пойти.

1

Вы можете использовать datutil.parser:

from lxml import etree 
from datetime import datetime 
from dateutil.parser import parse 

a = '''<root>  
    <A class="a" version="7"> 
     <details> 
      <dates> 
      <status date="2013-04-29T04:16:49.792-04:00">ACCEPTED</status> 
      <status date="2013-08-12T04:08:23.773-04:00">ACCEPTED</status> 
      </dates> 
     </details> 
    </A> 
    <A class="b" version="8"> 
     <details> 
      <dates> 
      <status date="2012-04-29T04:16:49.792-04:00">ACCEPTED</status> 
      <status date="2012-08-12T04:08:23.773-04:00">ACCEPTED</status> 
      </dates> 
     </details> 
    </A> 
</root> ''' 

tree = etree.fromstring(a) 

# Set your begin time 
beginTime = parse('2013-08-12T00:00:0.000-04:00') 

# Loop through all A elements 
for A in tree.findall('A'): 
    # Get the last time of the A element 
    timeA = A.find('./details/dates/status[last()]') 

    # Parse the found date into a datetime element 
    date = parse(timeA.get('date')) 

    # Compare the beginTime with the found date 
    if beginTime < date: 

     # Do as you like 
     #print(date) 
+0

Спасибо, но это медленный способ сделать что-то –

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

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