XPath/XSLT выбрать всех братьев и сестер, включая самого себя

Я хочу, чтобы моя XSLT-проверка проверяла, пусты ли все <field> в случайных вкладках панели. Если все они пусты, я хочу, чтобы он возвращал <p>All are empty</p>, но если это не так, я хочу, чтобы содержимое panelTabs с полями находилось внутри <div id='tabItems'>, с той же позицией, что и в XML. Пожалуйста, помогите мне.

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>

Текущий 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" />

Пробовал только XSLT без последнего <panelTabs>

Требуемый вывод, что-то вроде:

<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>

person Grafit    schedule 11.12.2014    source источник
comment
Можете ли вы добавить panelTab с полями, имеющими некоторые значения, и показать ожидаемый результат для этого тоже..   -  person Lingamurthy CS    schedule 11.12.2014
comment
@LingamurthyCS Я отредактировал XML и хотел вывести свой пост.   -  person Grafit    schedule 11.12.2014


Ответы (2)


попробуйте эту таблицу стилей:

<?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>
person Joel M. Lamsen    schedule 11.12.2014
comment
Кажется, это работает, единственная проблема заключается в том, что все содержимое всех панелей PanelTabs (кроме одного с пустыми полями) печатается дважды. - person Grafit; 11.12.2014
comment
NVM, это я исправил, это была другая проблема. Отлично работает, большое спасибо! Есть ли простой способ сделать эту работу, когда есть переменное количество пустых полей? - person Grafit; 11.12.2014

Вы можете использовать следующее. Обратите внимание, что ваш вывод не является правильно сформированным XML. Если вы хотите, чтобы он был хорошо сформирован, добавьте корневой элемент.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<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[field[normalize-space() = '']]">
    <div class="tabItems">
        <p>All fields are empty</p>
    </div>
</xsl:template>
<xsl:template match="panelTabs[not(field)]">
    <div class="tabItems">
        <table>something</table>
    </div>
</xsl:template>
<xsl:template match="panelTabs/field">
    <p>
        <xsl:value-of select="." />
    </p>
</xsl:template>
</xsl:stylesheet>
person Lingamurthy CS    schedule 11.12.2014