Получить позицию с помощью XSLT (найти все узлы после определенного элемента) - PullRequest
3 голосов
/ 22 ноября 2011

Я пытаюсь сделать такое преобразование. Предположим, у меня есть файл XML:

 <name>
   <a>Andy</a>
   <b>Emma</b>
   <c>John</c>
   <d>Cindy</d>
   <e>May</e>
 </name>

А теперь я хочу выбрать все элементы после элемента <b>Emma</b>, поэтому вывод будет таким:

<new>
  <one>John</one>
  <one>Cindy</one>
  <one>May</one>
<new>

Я могу выполнить условие только вручную, объявив условие как

[position()>2]

Но есть ли способ получить позицию автоматически? Грубая идея, подобная этой:

[position()>Emma] или [position()>b]

Ответы [ 3 ]

12 голосов
/ 22 ноября 2011

Что вы можете сделать, это /name/*[. = 'Emma']/following-sibling::* или /name/b/following-sibling::*.

3 голосов
/ 22 ноября 2011

Вам не нужно получать позицию, вместо этого вы можете использовать [preceding-sibling::*[text() = 'Emma']] или [preceding-sibling::b].

2 голосов
/ 23 ноября 2011

Вот полное преобразование:

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

 <xsl:template match="/*">
     <new>
      <xsl:apply-templates select=
       "*[. = 'Emma']/following-sibling::*"/>
     </new>
 </xsl:template>

 <xsl:template match="*/*">
  <one><xsl:value-of select="."/></one>
 </xsl:template>
</xsl:stylesheet>

когда это преобразование применяется к предоставленному документу XML :

<name>
    <a>Andy</a>
    <b>Emma</b>
    <c>John</c>
    <d>Cindy</d>
    <e>May</e>
</name>

желаемый, правильный результат получается :

<new>
   <one>John</one>
   <one>Cindy</one>
   <one>May</one>
</new>

Другим вариантом является использование следующего шаблона совпадения :

*/*[not('Emma' = .|following-sibling::*)]

И полное преобразование теперь :

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

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

 <xsl:template match="*/*[not('Emma' = .|following-sibling::*)]">
  <one><xsl:value-of select="."/></one>
 </xsl:template>
 <xsl:template match="*/*" priority="0"/>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...