[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Nested filters, or filter too complicated.

Subject: Re: Nested filters, or filter too complicated.
From: "Michael Kay mike@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Wed, 17 Jan 2018 16:28:33 -0000
Re:  Nested filters
You're trying to do a join. That involves comparing items from two different
sets.

In SQL (and in mathematical predicate logic) you do this by binding "range
variables" to the items in each set, and then using predicates such as

where X.ref = Y.id

You can use the same approach in XSLT, but with caveats. Only with XSLT 3.0
are you allowed to bind variables within an XPath expression. But that's where
"." and "current() come in. Within a predicate, "." is used as an implicit
range variable for the set you are filtering. You can also sometimes use
"current()" as your second range variable. Or you can bind variables
explicitly using xsl:variable. The problem about using ".", however, is that
it changes its meaning in a nested predicate.

In this case in XSLT 2.0 upwards, current() rescues you:

>
match="type[.='Action'][$data/device-description/param[@name=current()/../bas
e-name]/@standard='no')] "

(Note I've avoided the use of text() here. It's much better to compare with
the string-value of the element, rather than with its text nodes - it will
continue to work, for example, if the text is split up by comments).

XSLT 2.0 defines that current() within a pattern refers to the node being
tested against the pattern. Unfortunately though (IIRC), XSLT 1.0 didn't allow
use of current() in patterns. But no-one is still using XSLT 1.0, are they???

Michael Kay
Saxonica


> On 17 Jan 2018, at 15:19, Kerry, Richard richard.kerry@xxxxxxxx
<mailto:richard.kerry@xxxxxxxx> <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx
<mailto:xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>> wrote:
>
>
> I am trying to use XSLT to process one XML file, which refers to data in
another, and I am having trouble with getting a filter to work.
>
> The first source file (device.xml) - the one that is actually processed by
the XSL - has entries like this:
>
> <device-description>
>   <device-value>
>     <base-name>PollNow</base-name>
>     <name>Poll Now</name>
>     <type>Action</type>
>   </device-value>
>   <device-value>
>     <base-name>StartupPollNow</base-name>
>     <name>Startup Poll Now</name>
>     <type>Action</type>
>   </device-value>
>   <device-value>
>     <base-name>Ping</base-name>
>     <name>Ping</name>
>     <type minimum-length="0" maximum-length="256" >String</type>
>   </device-value>
> </device-description>
>
> One of the templates is approximately as follows:
>
> <x:template match="type[text()='Action']" >
> <!-- do basic action. -->
> </x:template>
>
> This quite happily matches all the <device_name> elements where the <type>
has a text value pf "Action".
>
> However, I have a second XML file (device-3.xml) which contains some data
that I wish to use to modify the behaviour of the transform.  It has entries
like this:
>
> <device-description>
>    <param name="PollNow" standard="no" >
> <name>Poll Now</name>
> <description>normal poll</description>
>    </param>
>    <param name="StartupPollNow" standard="no" >
> <name>Startup Poll Now</name>
> <description>startup poll</description>
>    </param>
>    <param name="Ping">
>       <name>Ping</name>
>       <description>Ping-Pong</description>
>    </param>
> </device-description>
>
> The second file is accessed via a variable, as follows:
>   <x:variable name="data" select="document($in-file-3)"/>
>
>
> What I want to achieve is that for all <type> elements where there is a
corresponding <param> where base-name is the same as param/@name, I want a
different action.
>
> The additional template I have for this is currently as follows
>
> <x:template
match="type[text()='Action'][$data/device-description/param[@name=../base-nam
e/text()]/@standard='no')] " >
> <!-- do different action. -->
> </x:template>
>
> My thinking is that the first filter is as with the first template I listed,
matching all <type> elements whose text is "Action".
> The second filter should then enable me to pick the right param from the
second file, and do something based on the value of its @standard.
> Maybe once I'm in the second filter I am causing confusion as to which
element the @name refers to (which should be the param) and which the
../base-name is relative to (the device-value/type)?
>
> Can I do all this within a single template's @match ?  Or am I making it too
complicated.  In which case how might I get the result I'm looking for?
>
>
> Appreciatively,
> Richard.
>
>
> The examples are all slightly simplified from the real data, which has more
elements, and the transforms are in a mode.
>
>
>
>
> Richard Kerry
> BNCS Engineer, SI SOL Telco & Media Vertical Practice
> T: +44 (0)20 3618 2669
> M: +44 (0)7812 325518
> 4 Triton Square, Regents Place, London NW1 3HG
> richard.kerry@xxxxxxxx
<https://webmail.siemens-it-solutions.com/owa/redir.aspx?C=9fb20d019e3e4cb993
44d708709a3177&URL=mailto%3arichard.kerry%40atos.net>
>
>
>
>
>
>
>
> This e-mail and the documents attached are confidential and intended solely
for the addressee; it may also be privileged. If you receive this e-mail in
error, please notify the sender immediately and destroy it. As its integrity
cannot be secured on the Internet, the Atos group liability cannot be
triggered for the message content. Although the sender endeavours to maintain
a computer virus-free network, the sender does not warrant that this
transmission is virus-free and will not be liable for any damages resulting
from any virus transmitted.
>
> Atos, Atos Consulting, Worldline and Canopy The Open Cloud Company are
trading names used by the Atos group. The following trading entities are
registered in England and Wales: Atos IT Services UK Limited (registered
number 01245534), Atos Consulting Limited (registered number 04312380), Atos
Worldline UK Limited (registered number 08514184) and Canopy The Open Cloud
Company Limited (registration number 08011902). The registered office for each
is at 4 Triton Square, Regents Place, London, NW1 3HG.The VAT No. for each
is: GB232327983.
>
> This e-mail and the documents attached are confidential and intended solely
for the addressee, and may contain confidential or privileged information. If
you receive this e-mail in error, you are not authorised to copy, disclose,
use or retain it. Please notify the sender immediately and delete this email
from your systems. As emails may be intercepted, amended or lost, they are not
secure. Atos therefore can accept no liability for any errors or their
content. Although Atos endeavours to maintain a virus-free network, we do not
warrant that this transmission is virus-free and can accept no liability for
any damages resulting from any virus transmitted. The risks are deemed to be
accepted by everyone who communicates with Atos by email.
> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
> EasyUnsubscribe <-list/293509> (by email <>)

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.