XSLT для ограничения количества дочерних узлов под родительским узлом - PullRequest
1 голос
/ 06 июня 2011

Извините, но в целом xslt нуб здесь

Данный XML выглядит так:

<Foo>
  <Bar />
  <Baz />
  <Qax />
  <FooBar />
</Foo>

Существует ли XSLT, который ограничит количество дочерних узлов в Foo, чтобы их было только 3?

Ответы [ 3 ]

2 голосов
/ 06 июня 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="node()|@*" name="identity">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="/*/*[position() > 3]"/>
</xsl:stylesheet>

При применении к предоставленному документу XML:

<Foo>
    <Bar />
    <Baz />
    <Qax />
    <FooBar />
</Foo>

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

<Foo>
   <Bar/>
   <Baz/>
   <Qax/>
</Foo>

Объяснение

  1. Правило / template копирует каждый узел "как есть".

  2. У нас есть только один дополнительный шаблон, который переопределяет правило идентификации для любого элемента, который является дочерним элементом верхнего элемента с положением, превышающим 3 . Этот шаблон ничего не имеет (имеет пустое тело), ​​что эффективно предотвращает копирование любого такого элемента в вывод (или, как мы говорим, «удаляет» его).

Примечание :

  1. Использование и переопределение правила идентификации является наиболее фундаментальным и мощным шаблоном проектирования XSLT .

  2. Рекомендуется использовать этот шаблон проектирования поверх простых <xsl:copy-of>, , поскольку он позволяет не только копировать узлы, но и обрабатывать их любым предоставленным нами шаблоном. Атрибуты всех элементов также обрабатываются.

0 голосов
/ 06 июня 2011

Есть три способа сделать это:

Во-первых, вы можете указать шаблону, который обрабатывает элемент Foo, обрабатывать только первые три дочерних узла:

<xsl:template match="Foo">
  <xsl:copy> <!-- can substitute with 'Foo' in this instance -->
    <xsl:apply-templates select="*[position() &lt;= 3]" />
  </xsl:copy>
</xsl:template>

Илиесли первые три дочерних узла не нуждаются в какой-либо отдельной обработке, вы можете использовать такой шаблон для обработки дочерних элементов:

<xsl:template match="Foo/*[position() &lt;= 3]">
  <!-- process the child element here -->
</xsl:template>

Два недостатка этого подхода состоят в том, что оставшиеся дочерние элементы Foo может обрабатываться другими шаблонами, например, если у вас был один для специальной обработки FooBar узлов, а также нет простого способа обработки элементов Bar и Baz по-другому.

Третий методиспользовать пустой шаблон, который применяется ко всем дочерним узлам Foo после третьего, например:

<xsl:template match="Foo/*[position() &gt; 3]" />

Этот метод также дает вам преимущество, заключающееся в возможности применения отдельных шаблонов для Bar и Baz, если вам нужно.

0 голосов
/ 06 июня 2011
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="/Foo">
        <xsl:copy>
            <xsl:copy-of select="*[position()&lt;4]"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

получает:

<Foo>
   <Bar/>
   <Baz/>
   <Qax/>
</Foo>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...