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

Re: Using node-set variables in predicates (another no

Subject: Re: Using node-set variables in predicates (another node comparison question)
From: "Chris Papademetrious christopher.papademetrious@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 4 Jan 2022 20:36:52 -0000
Re:  Using node-set variables in predicates (another no
Hi Dimitre,

That is good advice about functions b I will keep it in mind!


Hi everyone,

So I ran into a limitation of using document node-set variables in template
match expressions:

  <!-- put document nodes in $trim-elements -->
  <xsl:variable name="trim-elements"
select="//(desc|dt|entry|glossterm|li|p|shortdesc|title)"/>

  <!-- reference elements in $trim-elements -->
  <xsl:template match="text()
                       [matches(., '^\s+')]
                       [ancestor::*[. intersect
$trim-elements][not(descendant::*[. intersect $trim-elements])]]
                       [not(ancestor-or-self::node()
                         [ancestor::*[. intersect
$trim-elements][not(descendant::*[. intersect $trim-elements])]]
                         [preceding-sibling::node()])]">

When I constructed a temporary <p> node in a variable:

xsl:variable name="temporary-p">
   <p><xsl:copy-of select=bb&blah blahb&b></p>
</xsl:variable>

then called <xsl:apply-templates> to apply the template:

<xsl:apply-templates select="$temporary-p"/>

the template did not get applied. This makes perfect sense b my temporary
<p> variable does not contain any document nodes at all, so the template match
expression would never match!

But with Dimitrebs advice about functions fresh in my mind, I converted my
document-node variable into a node-type function:

  <xsl:function name="mine:is-trim-element" as="xs:boolean">
    <xsl:param name="elt" as="node()"/>
    <xsl:value-of select="exists($elt[self::desc or self::dt or self::endnote
or self::entry or self::example-title or self::glossterm or self::li or
self::msg-severity or self::p or self::shortdesc or self::title or
self::value-allowed or self::value-default or self::value-type])"/>
  </xsl:function>

Now I can use the function instead of the variable in the match expression:

  <xsl:template match="text()
                       [matches(., '^\s+')]
                       [ancestor::*[mine:is-trim-element(.)][not(descendant::
*[mine:is-trim-element(.)])]]
                       [not(ancestor-or-self::node()
                         [ancestor::*[mine:is-trim-element(.)][not(descendant
::*[mine:is-trim-element(.)])]]
                         [preceding-sibling::node()[not(mine:is-invisible(.))
]])]">

and the template applies as expected to my temporary variable!

Follow-up question b is there some syntactic sugar that would allow me to
write

self::(a|b|c)

instead of

(self::a or self::b or self::c)

or some other way of testing the element type in $elt altogether? I have
another function that matches several dozen element types, and a more compact
representation would be nice. I thought about matching local-name() against a
list of tag names using bintersectb, but that is not much shorter and it
seems operationally clunkier.

Thanks, this has been an enjoyable exercise for learning!


  *   Chris

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.