Perl Xpath:日期年份之前的搜索项目

时间:2012-06-24 14:08:10

标签: perl date xpath

我有一个包含电影的xml数据库,例如:

<film id="5">
        <title>The Avengers</title>
        <date>2012-09-24</date>
        <family>Comics</family>
</film>

从Perl脚本我想按日期找到电影。 如果我搜索一个特殊年份的电影,例如:

my $query = "//collection/film[date = 2012]";

它完全奏效并返回2012年的所有电影,但如果我在一年之前搜索所有电影,它就不起作用,例如:

my $query = "//collection/film[date < 2012]";

它返回所有电影..

3 个答案:

答案 0 :(得分:4)

嗯,像往常一样,有不止一种方法可以做到这一点。你要么让XPath工具知道它应该比较日期(它从一开始就不知道)用这样的东西:

my $query = '//collection/film[xs:date(./date) < xs:date("2012-01-01")]';

...或者你只是咬紧牙关,只是比较&#39; yyyy&#39;子:

my $query = '//collection/film[substring(date, 1, 4) < "2012"]';

我想,前者在语义上更好,但需要一个支持XPath 2.0的高级XML解析器工具。后者使用XML :: XPath成功验证。

更新:我想解释您的第一个查询有效的原因。 )看,你没有比较那里的日期 - 你比较数字,但只是因为&#39; =&#39;运营商。引自the doc

  

当要比较的对象都不是节点集且运算符是=时   或!=,然后通过将对象转换为公共对象来比较对象   键入如下,然后比较它们。如果至少有一个对象   比较是一个布尔值,然后将要比较的每个对象转换为   一个布尔值,好像通过应用布尔函数。否则,如果在   至少有一个要比较的对象是一个数字,然后是每个对象   比较被转换为数字,就像应用数字一样   功能

请参阅?你的2012-09-24&#39;被转换为数字 - 并成为2012年。当然,这相当于2012年。)

这并不适用于任何其他比较运算符:这就是为什么你需要使用substring,或者将date-string转换为数字的原因。我认为第一种方法更具可读性 - 也许更快。 )

答案 1 :(得分:1)

使用此XPath来检查年份

//collection/film[substring-before(date, '-') &lt; '2012']

您的Perl脚本将是,

my $query = "//collection/film[substring-before(date, '-') &lt; '2012']";

OR

my $query = "//collection/film[substring-before(date, '-') = '2012']";

答案 2 :(得分:0)

只需使用

//collection/film[translate(date, '-', '') < 20120101]

这会从日期中删除破折号,然后将其与2012-01-01(删除破折号)进行比较。

以同样的方式,您可以在指定日期之前获得所有日期(不仅仅是年份)的电影:

//collection/film[translate(date, '-', '') < translate($theDate, '-', '']