Как получить позицию родительского элемента - XSL - PullRequest
1 голос
/ 02 апреля 2010

Я хотел бы сделать следующее в xsl, но, к сожалению, parent / position () недопустим.

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>

У кого-нибудь есть идеи, как решить эту проблему из WITHIN моего совпадения с шаблоном для li?

Спасибо!

Ответы [ 4 ]

5 голосов
/ 03 апреля 2010

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

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

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

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

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

2 голосов
/ 02 апреля 2010

Хороший способ сделать это в 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, и нет необходимости пытаться сравнивать какие-либо позиции.

1 голос
/ 04 апреля 2010

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

<xsl:template match="li">
  <bullet>
    <xsl:apply-templates/>
  </bullet>
  <xsl:if test="position()=last() and not(../following-sibling::p)">
    <footer/>
  </xsl:if>
</xsl:template>
0 голосов
/ 03 апреля 2010

Если я правильно понимаю, вы ищете последние 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...