python xpath:比较日期
python xpath: Compare dates
我有这个简化的 xml 有很多 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="a" version="7">
...
</root>
如何使用 lxml xpath.[=16 仅获取最后状态日期大于特定时间点的那些 A
元素=]
到目前为止我做了什么:
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' ]");
但是这段代码的问题在于,出于某种原因,比较 returns 总是 false,所以 res
总是 空.
如有任何帮助或建议,我们将不胜感激。
xpath 1.0 中没有日期类型,您不能将 xpath 1.0 中的字符串与 =
和 !=
以外的运算符进行比较。 python 中有一个支持 xpath 2 的一部分的软件包,但我从未尝试过(请参阅 here)。这可能是一条路要走。
您可以使用 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)
您需要翻译和比较数字:
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 格式所以可以安全地比较,如果您有不同的偏移量或位数,那么您将不得不作为日期时间对象进行比较。
我有这个简化的 xml 有很多 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="a" version="7">
...
</root>
如何使用 lxml xpath.[=16 仅获取最后状态日期大于特定时间点的那些 A
元素=]
到目前为止我做了什么:
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' ]");
但是这段代码的问题在于,出于某种原因,比较 returns 总是 false,所以 res
总是 空.
如有任何帮助或建议,我们将不胜感激。
xpath 1.0 中没有日期类型,您不能将 xpath 1.0 中的字符串与 =
和 !=
以外的运算符进行比较。 python 中有一个支持 xpath 2 的一部分的软件包,但我从未尝试过(请参阅 here)。这可能是一条路要走。
您可以使用 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)
您需要翻译和比较数字:
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 格式所以可以安全地比较,如果您有不同的偏移量或位数,那么您将不得不作为日期时间对象进行比较。