XSLT для сегментации XML - PullRequest
       2

XSLT для сегментации XML

1 голос
/ 01 декабря 2010

У меня есть 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>

В редакторе Oxygen XML я могу использовать следующий XPath для достижения этой цели:

/company/employee[position() < (last() - count(/company/employee)+4)]

, но мне действительно нужно использовать XSLT в этом случае
Спасибо за вашу помощь

Ответы [ 3 ]

2 голосов
/ 01 декабря 2010

Я могу использовать следующую 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>
2 голосов
/ 01 декабря 2010

Как я могу использовать шаблон 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>

Примечание :

  1. Правило идентификации используется для копирования каждого узла "как есть".

  2. Существует только один конкретный шаблон, переопределяющий шаблон идентификации . Он соответствует любому элементу employee с позицией в списке узлов больше 3. Этот шаблон имеет пустое тело, что фактически отбрасывает соответствующие элементы.

0 голосов
/ 01 декабря 2010

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

<xsl:for-each select="company/employee[position() &lt; 3]">
  ...
</xsl:for-each>

Это может работать и с <template select=...., но я не уверен.

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