2010-04-02 4 views
0

То, что я хотел бы сделать в xsl, следующее, но неудачно parent/position() недопустим.Как получить положение родительского элемента - XSL

XSL

<xsl:template match="li"> 
    <bullet> 
    <xsl:apply-templates/> 
    </bullet> 
    <!-- if this is the last bullet AND there are no more "p" tags, output footer --> 
    <xsl:if test="count(ancestor::div/*) = parent/position()"> 
    <footer/> 
    </xsl:if> 
</xsl:template> 

XML

<html> 
    <div> 
    <p>There is an x number of me</p> 
    <p>There is an x number of me</p> 
    <p>There is an x number of me</p> 
    <ul> 
     <li>list item</li> 
     <li>list item</li> 
     <li>list item</li> 
     <li>list item</li> 
     <li>list item</li> 
    </ul> 
    </div> 
</html> 

Кто-нибудь есть какие-либо идеи, как выяснить эту проблему с ТЕЧЕНИЕ моего матча шаблон для LI?

Спасибо!

+0

@joe: Без ругательств, я повторяю, что это не в духе XSLT. Пожалуйста, покажите полный (но минимальный) пример с XML-документом, желаемым результатом и как результат должен быть получен из исходного XML-документа. Тогда многие люди смогут показать правильное решение, которое, вероятно, не будет сравнивать позиции. –

ответ

1

Попробуйте это:

<xsl:template match="li"> 
    <bullet> 
    <xsl:apply-templates/> 
    </bullet> 
    <xsl:if test="position()=last() and not(../following-sibling::p)"> 
    <footer/> 
    </xsl:if> 
</xsl:template> 
2

Хороший способ сделать это в XSLT является:

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

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

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

<xsl:template match="li"> 
    <bullet> 
    <xsl:apply-templates/> 
    </bullet> 
</xsl:template> 
</xsl:stylesheet> 

Включение <footer/> является наиболее естественным в конце шаблона, который соответствует div и нет никакой необходимости, чтобы попытаться сравнить любые позиции.

+0

Вы глубоко не осведомлены о последней строке моего вопроса. Мне нужно сделать это из WITHIN моего совпадения шаблонов для li. Это просто надуманный пример, который облегчает объяснение. – joe

+0

Но я смог реорганизовать свой код, чтобы работать так, как вы описали. Благодаря!С учетом сказанного я собираюсь оставить вопрос открытым, потому что перемещение

вне матча не всегда легко, если это большой файл xsl, где применяются шаблоны на «li», вызывается в нескольких местах. – joe

+0

@joe: Без каких-либо исключений я повторяю, что это не в духе XSLT. Пожалуйста, покажите полный (но минимальный) пример с XML-документом, желаемым результатом и как результат должен быть получен из исходного XML-документа. Тогда многие люди смогут показать правильное решение, которое, вероятно, не будет сравнивать позиции. –

0

Если я правильно понимаю, что вы ищете последние li; то есть li без li элементов, следующих за ним. Это можно проверить, как так:

<xsl:template match="li"> 
    <bullet> 
    <xsl:apply-templates/> 
    </bullet> 
    <xsl:if test="not(following-sibling::li)"> 
    <footer /> 
    </xsl:if> 
</xsl:template> 

Хотя в случае, если вы дали ему, кажется, больше в духе XSLT добавить колонтитул при обработке конца ul:

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

<xsl:template match="li"> 
    <bullet> 
    <xsl:apply-templates/> 
    </bullet> 
</xsl:template> 
4

вы можете найти положение родительского узла в дереве исходного кода путем подсчета своих предыдущих братьев:

<xsl:variable name="parent-position" 
       select="count(../preceding-sibling::*) + 1"/> 

Если вы хотите, чтобы определить, есть ли какие-либо p элементы после родительского элемента ul, вы можете проверить это без использования позиций на всех:

<xsl:if test="../following-sibling:p">...</xsl:test> 

Однако, как отметили Dimitre и Оливер, это больше в духе XSLT, чтобы добавить колонтитул при обработке родительского элемента , Кроме того, выражения XPath показывают только порядок в исходном исходном дереве. Если вы собираетесь фильтровать элементы или переупорядочивать с помощью xsl:sort перед обработкой, эти пути не будут работать по желанию, так как они будут смотреть на исходный порядок и включать все узлы в исходное дерево.

Смежные вопросы