xsl:if

1. How to test if child exists
2. How to deal with no summary
3. How do I test the name of the current node

1.

How to test if child exists

David Carlisle

How to test if there is only one child element and it's name is bva.

<xsl:if test="*[last() = 1 and self::bva]">

Jeni expands:

Or you could translate what you said in English into XSLT almost word for word:

 test="count(child::*) = 1 and bva"

Garry Paskin elaborates

> Pardon me, but I understand last() returns the order number of the last node
> of -any- node under the context node.

Yes, but don't forget XPath section 2.4: "A predicate filters a node-set with respect to an axis to produce a new node-set. For each node in the node-set to be filtered, the PredicateExpr is evaluated >> with that node as the context node << with the number of of nodes in the node-set as the context size and with the proximity position of the node in the node-set with respect to the axis as the context position ..."(emphasis added).

 <xsl:if test="bva[last() = 1]">

In the example above, the node-set to be filtered is the set of all bva nodes since that is to the left of the predicate. The predicate 'last() = 1' is evaluated with respect to _that_ node-set. So the first test above does indeed test to see if there is only one node in that node-set, in other words, if there is only one bva node.

2.

How to deal with no summary

Dan Machak

Q expansion:

 I have a XML file like this:

 <SECTION>
 <DATA>...</DATA>
 <DATA>...</DATA>
 <SUMMARY>..<SUMMARY>
 </SECTION>
 <SECTION>
 <DATA>...</DATA>
 <DATA>...</DATA>
 </SECTION>

 If there's no summary I want to output all <DATA> elements of a
 <SECTIONS> but if the summary is present I only want to output the
 <SUMMARY>:

 <SECTION>
 <SUMMARY>..<SUMMARY>
 </SECTION>
 <SECTION>
 <DATA>...</DATA>
 <DATA>...</DATA>
 </SECTION>





<xsl:stylesheet 
 xmlns:xsl="http://www.w3.org/1999/XSL/Tranform"     
version="1.0">

<xsl:template match="doc">
  <xsl:apply-templates/>
</xsl:template>

<xsl:template match="SECTION">
<SECTION>
<xsl:if test="count(SUMMARY)=0">
<xsl:apply-templates select="DATA"/>
</xsl:if>
<xsl:apply-templates select="SUMMARY"/>
</SECTION>
</xsl:template>

<!-- copy elements straight through -->
<xsl:template match="*|@*" priority="-1">
   <xsl:copy>
     <xsl:apply-templates select="@*|*|text()"/>
   </xsl:copy>
</xsl:template>

</xsl:stylesheet>
            

3.

How do I test the name of the current node

David Carlisle

	<xsl:when test="./sprogit">
	

You never need to start such a test with ./ that is equivalent to

		<xsl:when test="sprogit">

which is short for

		<xsl:when test="child::sprogit">

which tests if the current node has a spogit child. You want to test if the current node is a sprogit, which would be self::sprogit however doing such an xsl:choose is rather a strange way to code things, why not just apply-templates and then have separate templates matching each of the possible children?

Don Bruey offers

  <xsl:when test="name()='sprogit'">