| Subject: Re: [xsl] 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 | 
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 | 
|---|
| 
 | 
| <- Previous | Index | Next -> | 
|---|---|---|
| Re: [xsl] Using node-set variables , Dimitre Novatchev dn | Thread | Re: [xsl] Using node-set variables , Wendell Piez wapiez@ | 
| Re: [xsl] Using node-set variables , Dimitre Novatchev dn | Date | Re: [xsl] Using node-set variables , Wendell Piez wapiez@ | 
| Month |