Subject: RE: [xsl] Ways to simplify XSL, complex "select/filter criteria" From: "Michael Kay" <mike@xxxxxxxxxxxx> Date: Fri, 18 Dec 2009 10:23:36 -0000 |
I don't think I fully understand the requirement, but it's certainly a case where your code can be simplified by use of functions. For example you can define this function <xsl:function name="f:applies-now" as="xs:boolean"> <xsl:param name="v" as="element(ns:validFor)"/> <xsl:variable name="start" as="xs:dateTime?" select="xs:dateTime($v/ns:startDateTime)"/> <xsl:variable name="end" as="xs:dateTime?" select="xs:dateTime($v/ns:endDateTime)"/> <xsl:sequence select="(empty($start) or $start le current-dateTime()) and (empty($end) or $end ge current-dateTime()))"/> </xsl:function> and this one <xsl:function name="f:type" as="xs:QName"> <xsl:param name="e" as="element()"/> <xsl:sequence select="QName($e/@xsi:type, $e)"/> </xsl:function> and then you can do things like <xsl:value-of select="/cdm:Individual/cdm:PartyPlays [f:type(.) eq xs:QName("fn:Employee")] [exists(ns:validFor[f:applies-now(.)])]"/> Regards, Michael Kay http://www.saxonica.com/ http://twitter.com/michaelhkay > -----Original Message----- > From: Stefan Fritz [mailto:sfritz.nospam@xxxxxx] > Sent: 18 December 2009 10:07 > To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx > Subject: [xsl] Ways to simplify XSL, complex "select/filter criteria" > > 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,'Emp > loyee')][ > 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 |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Ways to simplify XSL, complex, Stefan Fritz | Thread | [xsl] Problem in Command Line, Byomokesh Sahoo |
Re: [xsl] retaining entity declarat, Andrew Welch | Date | [xsl] Problem in Command Line, Byomokesh Sahoo |
Month |