[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

[xsl] Ways to simplify XSL, complex "select/filter criteria"


Subject: [xsl] Ways to simplify XSL, complex "select/filter criteria"
From: Stefan Fritz <sfritz.nospam@xxxxxx>
Date: Fri, 18 Dec 2009 11:06:34 +0100

Hi all,

first my environment: Saxon 8.9, XSL and Xpath 2.0, Java

I have to transform a XML document which contains elements with the same name but different xs:type.
In addition the elements contain an optional validFor element which defines a time period for the validity of the data.


The rules to implement is:
- select element by xsi type
- select the valid (in time period) element
- if no time period specified and multiple elements of the same type exist, take the first one


I have to apply these rules in almost every value-of selection in my XSLT and therefore the XSLT became really a nightmare.
I hope there is a solution to simplify this. I though about xsl:function, dynamic Xpath (saxon:evaluate,..) but couldn't get it to work.
Any help more than appreciated!


Thanks
Stefan

simplified XML and XSL:

<ns:Individual
xsi:type="ns:Individual"
xmlns:ns="http://myns"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<ns:validFor xsi:type="ns:TimePeriod">
<ns:startDateTime>1800-01-01T00:00:00</ns:startDateTime>
<ns:endDateTime/>
</ns:validFor>

<ns:PartyPlays xsi:type="ns:Employee">
<ns:validFor xsi:type="ns:TimePeriod">
<ns:startDateTime>2005-09-19T00:00:00</ns:startDateTime>
<ns:endDateTime/>
</ns:validFor>
<ns:PartyRoleContactableVia xsi:type="ns:PostalContact">
                ...
</ns:PartyRoleContactableVia>
<ns:PartyRoleContactableVia xsi:type="ns:PostalContact">
            ...
</ns:PartyRoleContactableVia>
<ns:PartyRoleContactableVia xsi:type="ns:EMailContact">
<ns:validFor xsi:type="ns:TimePeriod">
<ns:endDateTime>2010-09-19T00:00:00</ns:endDateTime>
</ns:validFor>
<ns:eMailAddress>email1@xxxxxx</ns:eMailAddress>
</ns:PartyRoleContactableVia>
<ns:PartyRoleContactableVia xsi:type="ns:EMailContact">
<ns:validFor xsi:type="ns:TimePeriod">
<ns:endDateTime>2010-09-19T00:00:00</ns:endDateTime>
</ns:validFor>
<ns:eMailAddress>email2@xxxxxx</ns:eMailAddress>
</ns:PartyRoleContactableVia>
</ns:PartyPlays>
</ns:Individual>


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:cdm="http://myns" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:output method="text"/>


<xsl:template match="/">
<xsl:value-of select="/cdm:Individual/cdm:PartyPlays[contains(@xsi:type,'Employee')][
if(string-length(cdm:validFor/cdm:startDateTime) gt 0 and string-length(cdm:validFor/cdm:endDateTime) gt 0) then
(xs:dateTime(cdm:validFor/cdm:startDateTime) lt current-dateTime() and xs:dateTime(cdm:validFor/cdm:endDateTime)gt current-dateTime())
else if(string-length(cdm:validFor/cdm:startDateTime) gt 0) then
(xs:dateTime(cdm:validFor/cdm:startDateTime) lt current-dateTime())
else if(string-length(cdm:validFor/cdm:endDateTime) gt 0) then
( xs:dateTime(cdm:validFor/cdm:endDateTime)gt current-dateTime())
else
1
]/cdm:PartyRoleContactableVia[contains(@xsi:type,'EMailContact')][
if(string-length(cdm:validFor/cdm:startDateTime) gt 0 and string-length(cdm:validFor/cdm:endDateTime) gt 0) then
(xs:dateTime(cdm:validFor/cdm:startDateTime) lt current-dateTime() and xs:dateTime(cdm:validFor/cdm:endDateTime)gt current-dateTime())
else if(string-length(cdm:validFor/cdm:startDateTime) gt 0) then
(xs:dateTime(cdm:validFor/cdm:startDateTime) lt current-dateTime())
else if(string-length(cdm:validFor/cdm:endDateTime) gt 0) then
( xs:dateTime(cdm:validFor/cdm:endDateTime)gt current-dateTime())
else
1
][1]/cdm:eMailAddress[1]"/>
</xsl:template>
</xsl:stylesheet>



Current Thread
Keywords