Вопрос
У меня есть XML, который идет так:
<company>
<employee name="john"/>
<employee name="sarah"/>
<employee name="kim"/>
<employee name="karl"/>
<employee name="tom"/>
<employee name="jim"/>
<employee name="sandy"/>
</company>
Как я могу использовать шаблон XSLT для выбора только первых N узлов, 3, например, я могу получить:
<company>
<employee name="john"/>
<employee name="sarah"/>
<employee name="kim"/>
</company>
В редакторе XML Oxygen я могу использовать следующие XPath для достижения этого:
/company/employee[position() < (last() - count(/company/employee)+4)]
Но мне действительно нужно использовать XSLT в этом случае
Спасибо за вашу помощь
Решение
Как я могу использовать шаблон XSLT для выбора только первых N узлов, 3, например, я могу получить:
<company> <employee name="john"/> <employee name="sarah"/> <employee name="kim"/> </company>
Короткий ответ: Познавая чуть немного XPath и XSLT.
Полный (но все еще короткий) ответ:
Это преобразование:
<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()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="employee[position() > 3]"/>
</xsl:stylesheet>
При применении на прилагаемом документе XML:
<company>
<employee name="john"/>
<employee name="sarah"/>
<employee name="kim"/>
<employee name="karl"/>
<employee name="tom"/>
<employee name="jim"/>
<employee name="sandy"/>
</company>
производит желаемый, правильный результат:
<company>
<employee name="john"/>
<employee name="sarah"/>
<employee name="kim"/>
</company>
Записывать:
То правило личности используется скопировать каждый узел «как есть».
Есть только один конкретный шаблон, переопределяющий шаблон идентификатора. Отказ Это совпадает
employee
Элемент с положением в узле-списке больше, чем 3. Этот шаблон имеет пустое тело, эффективное отброс соответствующих элементов.
Другие советы
Я могу использовать следующие XPath для достижения этого:
/company/employee[position() < (last() - count(/company/employee)+4)]
Обратите внимание, что здесь last()
равно count(/company/employee)
, Так что это будет уменьшится к:
/company/employee[4 > position()]
В шаблоне вы могли бы иметь:
<xsl:template match="employee[4 > position()]">
...
</xsl:template>
То же самое с параметризацией (Remenber вы не можете использовать ссылку на параметр в шаблонах XSLT 1.0):
<xsl:param name="pTop" select="3"/>
<xsl:template match="employee">
<xsl:if test="$pTop >= position()">
...
</xsl:if>
</xsl:template>
Попробуй это:
<xsl:for-each select="company/employee[position() < 3]">
...
</xsl:for-each>
Это может работать с <template select=....
тоже, но я не уверен.