[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
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<>)
|
PURCHASE STYLUS STUDIO ONLINE TODAY!Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced! Download The World's Best XML IDE!Accelerate XML development with our award-winning XML IDE - Download a free trial today! Subscribe in XML format
|