Search code examples
xmlxsltxpathnodesaxes

XPath/XSLT select all siblings including self


I want my XSLT check to check whether or not all <field> in a random panelTabs are empty. If they are all empty, I want it to return <p>All are empty</p>, but if they are not, I want the content of the panelTabs with the fields to be inside the <div id='tabItems'>, the one with the same position as in the XML. Please help me.

XML:

<document>
 <contentTabs>
  <panelTabs text='a'>
   <row type='header'>
    <column>H1</column>
    <column>H2</column>
   </row>
   <row type='data'>
    <column>D1</column>
    <column>D2</column>
   </row>
  </panelTabs>
  <panelTabs text='b'>
   <field> </field>
   <field> </field>
  </panelTabs>
  <panelTabs text='c'>
   <field>x1</field>
   <field>x2</field>
  </panelTabs>
 <contentTabs>
</document>

Current XSLT:

<xsl:template match='contentTabs'>
 <ul id='ulTabKopjes' class='tabKopjes'>
  <li onclick='verschuifTabs(this)'>&#60;</li>
   <xsl:call-template name='liHeaders' />
  <li onclick='verschuifTabs(this)'>&#62;</li>
 </ul>
 <div class='tabContent'>
  <xsl:apply-templates />
 </div>
</xsl:template>

<xsl:template name='liHeaders'>
 <xsl:for-each select='panelTabs'>
  <li onclick='loadPanelTabContent(this)'>
   <xsl:value-of select="@text" />
  </li>
 </xsl:for-each>
</xsl:template>

<xsl:template match="panelTabs">
 <div class="tabItems">
  <xsl:attribute name="id">
   <xsl:text>tabnr</xsl:text><xsl:value-of select="position()" />
  </xsl:attribute>
  <xsl:apply-templates />
 </div> 
</xsl:template>

<xsl:template match="panelTabs[not(field[normalize-space()])]">
 <p>All are empty</p>
</xsl:template>

<xsl:template match="panelTabs/field">
 <p><xsl:value-of select="." /></p>
</xsl:template>

<xsl:template match="panelTabs/field[not(normalize-space())]" priority="2" />

Only tried the XSLT without the last <panelTabs>

Wanted output, something like:

<ul id='ulTabKopjes' class='tabKopjes'>
 <li onclick='verschuifTabs(this)'>&#60;</li>
 <li onclick='loadPanelTabContent(this)'>a</li>
 <li onclick='loadPanelTabContent(this)'>b</li>
 <li onclick='loadPanelTabContent(this)'>c</li>
 <li onclick='verschuifTabs(this)'>&#62;</li>
</ul>
<div id='tabContent'>
 <div class='tabItems' id='tabnr1'>
  <table>something</table>
 </div>
 <div class='tabItems' id='tabnr2'>
  <p>All fields are empty</p>
 </div>
 <div class='tabItems' id='tabnr3'>
  <p>x1</p>
  <p>x2</p>
 </div>
</div>

Solution

  • try this stylesheet:

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet 
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        version="1.0">
    
        <xsl:strip-space elements="*"/>
    
        <xsl:output indent="yes" omit-xml-declaration="yes"/>
    
        <xsl:template match='contentTabs'>
            <ul id='ulTabKopjes' class='tabKopjes'>
                <li onclick='verschuifTabs(this)'>&#60;</li>
                <xsl:call-template name='liHeaders' />
                <li onclick='verschuifTabs(this)'>&#62;</li>
            </ul>
            <div class='tabContent'>
                <xsl:apply-templates />
            </div>
        </xsl:template>
    
        <xsl:template name='liHeaders'>
            <xsl:for-each select='panelTabs'>
                <li onclick='loadPanelTabContent(this)'>
                    <xsl:value-of select="@text" />
                </li>
            </xsl:for-each>
        </xsl:template>
    
        <xsl:template match="panelTabs">
            <div class="tabItems">
                <xsl:attribute name="id">
                    <xsl:text>tabnr</xsl:text><xsl:value-of select="position()" />
                </xsl:attribute>
                <xsl:choose>
                    <xsl:when test="field and field = ''">
                        <p>All are empty</p>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:apply-templates />
                    </xsl:otherwise>
                </xsl:choose>
            </div> 
        </xsl:template>
    
        <xsl:template match="panelTabs/field[.!='']">
            <p><xsl:value-of select="." /></p>
        </xsl:template>
    
        <xsl:template match="panelTabs/row">
            <table>something</table>
        </xsl:template>
    
    </xsl:stylesheet>