I’m working with xslt for the first time. I have 2.0, but that’s about the only advantage I have access to with the c# transform library we have. I’m trying to count a number of child nodes in the XML document which contain a date more than 12 years ago and have a certain type attribute.
Sample xml structure:
<xml version=\"1.0\" encoding=\"utf-8\"?>
<... />
<Dependents>
<Dependent><DOB>1964-04-01</DOB><DependentType>Spouse</DependentType></Dependent>
<Dependent><DOB>2000-01-01</DOB><DependentType>Child</DependentType></Dependent>
<Dependent><DOB>2012-01-01</DOB><DependentType>Child</DependentType></Dependent>
</Dependents>
<... />
where <... /> signifies some extra unrelated stuff.
So essentially, I want the number of children younger than 12 years old. (I have the count of dependenttype = child of all ages working, it’s just the under 12 that’s giving me trouble). The approach that was suggested to me was to construct a variable that stands for 12 years ago from today and use that as a basis for comparison in the count() function. That sounds reasonable, but I’m stuck constructing the date without the use of 3rd party libraries (e.g. exslt) that are so often linked in questions like this for the easy, handy-dandy answers.
The xslt I’ve gotten so far for this is:
<xsl:variable name="today" select="current-dateTime()" as="xs:dateTime" />
<xsl:variable name="twelveyearsago" select="xs:dateTime(concat(year-from-dateTime($today) - 12, '-', month-from-dateTime($today), '-', day-from-dateTime($today)))" />
<xsl:text>12yearsago=</xsl:text><xsl:value-of select="$twelveyearsago" />
And it’s not working because the month-from-dateTime (and presumable day-from-dateTime) don’t add leading zeros. For today, March 21 2012 I’m getting back: Saxon.Api.DynamicError : Invalid dateTime value “2000-3-21” (Month must be two digits) (The W3Schools xpath function reference implies that they should, but they don’t.)
What I would like to output is:
<xsl:text>&numberofchildren=</xsl:text><xsl:value-of select="count(//InsuranceRequest/HealthInsurance/Dependents/Dependent/DependentType[text() = 'Child'])" />
<xsl:text>&childrenunder12=</xsl:text><xsl:value-of select="children under twelve" />
The more I pound my head against this, the more I feel like there’s a simpler approach that I’m just not seeing.
Edit: I cleaned up the xslt syntax so it’s valid and not a doubly-quoted c# string.
You can simply substract a duration of 12 years as in
<xsl:variable name="twelveyearsago" select="$today - xs:yearMonthDuration('P12Y')"/>, then use e.g.//Dependent[DependentType = 'Child' and xs:date(DOB) >= $twelveyearsago].[edit]
Here is a template that compiles and executes fine for with Saxon 9.4: