xsl-list
[Top] [All Lists]

Re: [xsl] Using node-set variables in predicates (another node comparison question)

2022-01-04 14:50:08
Hi Chris,

Consider something like this:

<xsl:function name="mine:is-trim-element" as="xs:boolean">
  <xsl:param name="elt" as="node()"/>
  <xsl:apply-templates mode="mine:is-trim" select="$elt"/>
</xsl:function>

<xsl:template match="*" mode="mine:is-trim" as="xs:boolean">
  <xsl:sequence select="false()"/>
</xsl:template>

<xsl:template match="desc | dt | endnote | entry | younameit"
mode="mine:is-trim" as="xs:boolean">
  <xsl:sequence select="true()"/>
</xsl:template>

Essentially the function is an accessor for an apply-templates operation
that implements the filter.

Good luck, Wendell


On Tue, Jan 4, 2022 at 3:37 PM Chris Papademetrious
christopher(_dot_)papademetrious(_at_)synopsys(_dot_)com <
xsl-list-service(_at_)lists(_dot_)mulberrytech(_dot_)com> wrote:

Hi Dimitre,



That is good advice about functions – 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=”…blah blah…”></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 – my temporary
<p> variable does not contain any document nodes at all, so the template
match expression would never match!



But with Dimitre’s 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 – 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 “intersect”, but that is not much shorter
and it seems operationally clunkier.



Thanks, this has been an enjoyable exercise for learning!



   - Chris




XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/174322> (by
email <>)



-- 
...Wendell Piez... ...wendell -at- nist -dot- gov...
...wendellpiez.com... ...pellucidliterature.org... ...pausepress.org...
...github.com/wendellpiez... ...gitlab.coko.foundation/wendell...
--~----------------------------------------------------------------
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
EasyUnsubscribe: http://lists.mulberrytech.com/unsub/xsl-list/1167547
or by email: xsl-list-unsub(_at_)lists(_dot_)mulberrytech(_dot_)com
--~--
<Prev in Thread] Current Thread [Next in Thread>