XSLT 1.0 - Conditional Assignment of Node

using pure XSLT 1.0, how can I conditionally assign a node. I am trying something like this, but it is not working.

<xsl:variable name="topcall" select="//topcall"/>
<xsl:variable name="focusedcall" select="//focusedcall" />

<xsl:variable name="firstcall" select="$topcall | $focusedcall"/>

For the variable, firstcallI am conditionally selecting node. if there is topcall, then assign it firstcall, assign others firstcall focusedcall.

+5
source share
3 answers

I. Solution XSLT 1.0 . This short (30 lines), simple and parameterized conversion works with any number of node types:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:param name="pRatedCalls">
   <call type="topcall"/>
   <call type="focusedcall"/>
   <call type="normalcall"/>
 </xsl:param>

 <xsl:variable name="vRatedCalls" select=
  "document('')/*/xsl:param[@name='pRatedCalls']/*"/>

 <xsl:variable name="vDoc" select="/"/>

 <xsl:variable name="vpresentCallNames">
  <xsl:for-each select="$vRatedCalls">
   <xsl:value-of select=
   "name($vDoc//*[name()=current()/@type][1])"/>
   <xsl:text> </xsl:text>
  </xsl:for-each>
 </xsl:variable>

 <xsl:template match="/">
  <xsl:copy-of select=
   "//*[name()
       =
        substring-before(normalize-space($vpresentCallNames),' ')]"/>
 </xsl:template>
</xsl:stylesheet>

When applied to this XML document (note that the order of the documents does not match the specified priorities in the parameter pRatedCalls):

<t>
 <normalcall/>
 <focusedcall/>
 <topcall/>
</t>

, :

<topcall/>

, XML-:

<t>
 <normalcall/>
 <focusedcall/>
</t>

:

<focusedcall/>

  • , ( ), ( ) $pRatedCalls.

  • $vpresentCallNames , , type call in the $pRatedCalls `, XML.

  • , , , , .

II. XSLT 2.0:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:param name="pRatedCalls" select=
  "'topcall', 'focusedcall', 'normalcall'"/>

 <xsl:template match="/">
  <xsl:sequence select=
   "//*
     [name()=$pRatedCalls
                [. = current()//*/name()]
                                        [1]
     ]"/>
 </xsl:template>
</xsl:stylesheet>
+2

:

<xsl:variable name="firstcall" select="$topcall[$topcall] |
                                       $focusedcall[not($topcall)]" />

, $topcall, $topcall nodeet ; $focusedcall, $topcall nodeet .

" 5-6 ":

, 5-6 , .. 3-4, $topcall $focuscall...

- <xsl:choose>:

<xsl:variable name="firstcall">
  <xsl:choose>
    <xsl:when test="$topcall">    <xsl:copy-of select="$topcall" /></xsl:when>
    <xsl:when test="$focusedcall"><xsl:copy-of select="$focusedcall" /></xsl:when>
    <xsl:when test="$thiscall">   <xsl:copy-of select="$thiscall" /></xsl:when>
    <xsl:otherwise>               <xsl:copy-of select="$thatcall" /></xsl:otherwise>
  </xsl:choose>
</xsl:variable>

XSLT 1.0 (RTF: , XML). - XPath $firstcall, . XPath $firstcall , . select="$firstcall[1]", ...

  • <xsl:when> <xsl:otherwise>, , RTF. ,
  • node-set(), RTF , XPath. XSLT-, . ,
  • XSLT 2.0, RTF . , XPath 2.0 if/then/else XPath, .
  • XPath 1.0, ,

:

select="$topcall[$topcall] |
        ($focusedcall[$focusedcall] | $thiscall[not($focusedcall)])[not($topcall)]"

, . , XPath 2 $focuscall

($focusedcall[$focusedcall] | $thiscall[not($focusedcall)])

$thiscall

($thiscall[$thiscall] | $thatcall[not($thiscall)])

.

, , , .

+5

Does <xsl:variable name="firstcall" select="($topcall | $focusedcall)[1]"/>what you want do? This is usually a way to take the first node in the document order of various types of nodes.

+3
source

All Articles