Reputation: 107
I have the following XML
<LIST>
<FIELD name="D22" value="2005-05-03Z" />
<ELEMENT name="QX55">
<ELEMENT name="QX553" value="2004-01-01Z" />
</ELEMENT>
<ELEMENT name="QX55">
<ELEMENT name="QX553" value="2005-04-26Z" />
</ELEMENT>
<ELEMENT name="QX55">
<ELEMENT name="QX553" value="2005-05-01Z" />
</ELEMENT>
<ELEMENT name="QX55">
<ELEMENT name="QX553" value="2006-01-01Z" />
</ELEMENT>
<ELEMENT name="QX55">
<ELEMENT name="QX553" value="2005-05-03Z" />
</ELEMENT>
</LIST>
I am trying to create a xslt mapping that would remove all QX25 elements with @value date before the date in @value field D22
I am applying the filter by using the element:
<xsl:template match="">
I know that xslt cannot compare dates so I suspect this would have to be done by substring but I don't know how to apply substring in the match attribute. Also I cannot use any extensions to xslt
This is what I tried so far: I only tried to get it working for comparing years so far but it's giving me a parse exception
<xsl:variable name="d22date">
<xsl:value-of select="/LIST/FIELD[@name='D22']/@value" />
</xsl:variable>
<xsl:template match="//ELEMENT[@name='QX55'][ELEMENT[@name='QX553' and substring(@value,0,5)<substring($d22date,0,5)]]"/>
Can anyone help me with this match attribute?
I am using xslt 2.0
Upvotes: 1
Views: 753
Reputation: 70638
You are not far off, but there are a few things wrong with your current attempt:
<
needs to be escaped as <
in the expressionsubstring
starts at 1, not 0.This means your template should really look like this:
<xsl:template match="ELEMENT
[@name='QX55']
[ELEMENT[@name='QX553' and substring(@value, 1, 10) < substring($d22date, 1, 10)]]"/>
Note that it is not true to say that XSLT can't compare dates. XSLT 2.0 does have many date/time functions. For example, you could write your XSLT like this
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" indent="yes" />
<xsl:variable name="d22date" select="/LIST/FIELD[@name='D22']/@value" as="xs:date" />
<xsl:template match="ELEMENT[@name='QX55'][ELEMENT[@name='QX553' and xs:date(@value) < $d22date]]"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1