[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: "Eliot Kimber eliot.kimber@xxxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 4 Jan 2022 20:52:36 -0000
Re:  Using node-set variables in predicates (another no
Note that this 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>

Should use xsl:sequence instead of value-of as you want to return a Boolean
value.

By using value-of you are effectively constructing a Boolean (result of
exists()) then converting that to a text node (result of value-of) and then
XSLT implicitly converts that back to a Boolean using the string value of the
text node.

In general, you almost always want xsl:sequence unless what you really want is
a text node (for example, because youre contributing to the content of a
result element).

[Wendell beat me to this suggestion but Id already written it:]

As for the question of determining the type: I think I would follow Dimitres
advice and use templates :

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

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

<xsl:template mode= mine:is-trim-element as=xs:Boolean priority=-1
match=*>
  <xsl:sequence select=false()
</xsl:template>

This makes the logic for determining type extensible using normal extension
mechanisms.

Cheers,

E.

_____________________________________________
Eliot Kimber
Sr Staff Content Engineer
O: 512 554 9368
M: 512 554 9368
servicenow.com<https://www.servicenow.com>
LinkedIn<https://www.linkedin.com/company/servicenow> |
Twitter<https://twitter.com/servicenow> |
YouTube<https://www.youtube.com/user/servicenowinc> |
Facebook<https://www.facebook.com/servicenow>

From: Chris Papademetrious christopher.papademetrious@xxxxxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Tuesday, January 4, 2022 at 2:37 PM
To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx <xsl-list@xxxxxxxxxxxxxxxxxxxxxx>
Subject: Re:  Using node-set variables in predicates (another node
comparison question)
[External Email]

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 Dimitres 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<https://urldefense.com/v3/__http:/www.mulberrytech.com/xsl/xsl-list__
;!!N4vogdjhuJM!QoTfzk5BnM0e2UXvfQdi8oQSTETaMkscgawE6XS1ls6pK21OytP7rdlPobZYmh
yWkmh8Ow$>
EasyUnsubscribe<https://urldefense.com/v3/__http:/lists.mulberrytech.com/unsu
b/xsl-list/3453418__;!!N4vogdjhuJM!QoTfzk5BnM0e2UXvfQdi8oQSTETaMkscgawE6XS1ls
6pK21OytP7rdlPobZYmhxv1pEexw$> (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.