|
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 |