Question
J'ai un fichier XML qui va comme ceci:
<company>
<employee name="john"/>
<employee name="sarah"/>
<employee name="kim"/>
<employee name="karl"/>
<employee name="tom"/>
<employee name="jim"/>
<employee name="sandy"/>
</company>
Comment puis-je utiliser un modèle XSLT pour sélectionner seulement les premiers noeuds n, 3 par exemple, pour que je puisse obtenir:
<company>
<employee name="john"/>
<employee name="sarah"/>
<employee name="kim"/>
</company>
Dans l'éditeur XML d'oxygène, je peux utiliser la XPath suivante pour y parvenir:
/company/employee[position() < (last() - count(/company/employee)+4)]
mais je vraiment besoin d'utiliser XSLT dans ce cas
Merci pour votre aide
La solution
Comment puis-je utiliser un modèle XSLT pour en sélectionnant seulement les premiers noeuds n, 3 par exemple, pour que je puisse obtenir:
<company> <employee name="john"/> <employee name="sarah"/> <employee name="kim"/> </company>
La réponse :. En connaissant un peu XPath et XSLT
complète (mais courte) réponse :
Cette transformation :
<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>
lorsqu'il est appliqué sur le document XML fourni :
<company>
<employee name="john"/>
<employee name="sarah"/>
<employee name="kim"/>
<employee name="karl"/>
<employee name="tom"/>
<employee name="jim"/>
<employee name="sandy"/>
</company>
produit le voulait, résultat correct :
<company>
<employee name="john"/>
<employee name="sarah"/>
<employee name="kim"/>
</company>
Prenez note :
-
La règle identité est utilisé pour copier chaque nœud "en l'état".
-
Il y a juste un modèle spécifique remplaçant le modèle d'identité . Il correspond à tout élément de
employee
avec la position dans le noeud-list supérieur à 3. Ce modèle a un corps vide, en éliminant efficacement les éléments appariés.
Autres conseils
Je peux utiliser la XPath suivante y parvenir:
/company/employee[position() < (last() - count(/company/employee)+4)]
Notez que la last()
ici est égal à count(/company/employee)
, ce sera donc réduit à:
/company/employee[4 > position()]
Dans un modèle que vous pourriez avoir:
<xsl:template match="employee[4 > position()]">
...
</xsl:template>
La même chose avec paramétrisation (Remenber vous ne pouvez pas utiliser des paramètres de référence dans les modèles XSLT 1.0):
<xsl:param name="pTop" select="3"/>
<xsl:template match="employee">
<xsl:if test="$pTop >= position()">
...
</xsl:if>
</xsl:template>
Essayez ceci:
<xsl:for-each select="company/employee[position() < 3]">
...
</xsl:for-each>
Ce travail de force avec <template select=....
aussi, mais je ne suis pas sûr.