xpath dates comparison
Asked Answered
L

2

20

I'm trying to filter elements based on an attribute that is a date in the format yyyy-MM-dd.

My XML looks like this:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <article title="wired" pub-date="2010-11-22" />
  <article title="Plus 24" pub-date="2010-11-22" />
  <article title="Finance" pub-date="2010-10-25" />
</root>

My xpath attempt:

'//article[xs:date(./@pub-date) > xs:date("2010-11-15")]'

Using xpath 2.0 - would avoid adding a schema unless absolutely necessary.

From comments:

I believe I must be missing something then. Is it possible that I need to specify something else for xs:date to work? Maybe a xs: namespace definition?

Lockjaw answered 3/12, 2010 at 16:0 Comment(5)
@Razor: What is the question? See no problem here, just style: a wouldn't use a starting ./ step, only for brevity one could use (for other expression) .// instead of descendant::.Godliman
Your XPath 2.0 expression should do, I would use //article[xs:date(@pub-date) gt xs:date("2010-11-15")] however which is a bit shorter and more compact.Mothball
Works for me in Oxygen/XML. Why do you think this doesn't work?Plaice
I believe I must be missing something then. Is it possible that I need to specify something else for xs:date to work? Maybe a xs: namespace definition?Lockjaw
@Razor: Yes, yes, yes...Godliman
N
34

In both XPath 1.0 and 2.0 you can use:

//article[number(translate(@pub-date,'-','')) > 20101115]

Your XPath 2.0 expression is correct, using Saxon 9.0.3 this transformation:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xsl:template match="/">
      <xsl:sequence select="//article[xs:date(./@pub-date) > xs:date('2010-11-15')]"/>
    </xsl:template>
</xsl:stylesheet>

when applied on the provided XML document:

<root>
  <article title="wired" pub-date="2010-11-22" />
  <article title="Plus 24" pub-date="2010-11-22" />
  <article title="Finance" pub-date="2010-10-25" />
</root>

produces the wanted, correct result:

<article title="wired" pub-date="2010-11-22"/>
<article title="Plus 24" pub-date="2010-11-22"/>
Norbertonorbie answered 3/12, 2010 at 18:22 Comment(3)
nice solution, +1 - it's a workaround tho, but will mark this as the answer if I cannot find what's wrong with my codeLockjaw
@Razor: I have updated my answer with a complete XSLT 2.0 solution showing that your XPath 2.0 expression is correct.Norbertonorbie
Not working even after adding an inline XML schema, so the issue has to be my xpath parser (velocity XMLtool). Your first solution almost works - you have an extra ) before the closing ], please correct that and I'll mark this as an answer.Lockjaw
U
2
<cfset startdatetime = Now() >
<cfset nNow = LSParseNumber(DateFormat(DateAdd('n', -15,startdatetime),'yyyyMMddHHmm')) >

number(substring(concat(translate(text(),'-: ',''),'0000000000000000'),1,12))<=#nNow#
Upu answered 6/10, 2011 at 14:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.