Je dois transformer certaines données XML en une liste paginée de champs. Voici un exemple.XSLT: une variante du problème de pagination
XML Entrée:
<?xml version="1.0" encoding="UTF-8"?>
<data>
<books>
<book title="t0"/>
<book title="t1"/>
<book title="t2"/>
<book title="t3"/>
<book title="t4"/>
</books>
<library name="my library"/>
</data>
sortie souhaitée:
<?xml version="1.0" encoding="UTF-8"?>
<pages>
<page number="1">
<field name="library_name" value="my library"/>
<field name="book_1" value="t0"/>
<field name="book_2" value="t1"/>
</page>
<page number="2">
<field name="book_1" value="t2"/>
<field name="book_2" value="t3"/>
</page>
<page number="3">
<field name="book_1" value="t4"/>
</page>
</pages>
Dans l'exemple ci-dessus, je suppose que je veux dans la plupart des 2 champs nommés book_n
(avec n
compris entre 1 et 2) par page . Les tags <page>
doivent avoir un attribut number
. Enfin, le champ library_name
doit apparaître seulement le premier <page>
.
Voici ma solution actuelle en utilisant XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0"
exclude-result-prefixes="trx xs">
<xsl:output method="xml" indent="yes" omit-xml-declaration="no" />
<xsl:variable name="max" select="2"/>
<xsl:template match="//books">
<xsl:for-each-group select="book" group-ending-with="*[position() mod $max = 0]">
<xsl:variable name="pageNum" select="position()"/>
<page number="{$pageNum}">
<xsl:for-each select="current-group()">
<xsl:variable name="idx" select="if (position() mod $max = 0) then $max else position() mod $max"/>
<field value="{@title}">
<xsl:attribute name="name">book_<xsl:value-of select="$idx"/>
</xsl:attribute>
</field>
</xsl:for-each>
<xsl:if test="$pageNum = 1">
<xsl:call-template name="templateFor_library"/>
</xsl:if>
</page>
</xsl:for-each-group>
</xsl:template>
<xsl:template name="templateFor_library">
<xsl:for-each select="//library">
<field name="library_name" value="{@name}" />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Y at-il une meilleure/façon plus simple d'effectuer cette transformation?
Great! Je vous remercie! Et comment vous assurer que le champ nommé nom_bibliothèque apparaît uniquement sur le premier élément? –
MarcoS
@MarcoS: Voir la solution modifiée. Je déconseillerais fortement cela, cependant. Le nom de la bibliothèque est une partie logique de l'élément '' et devrait aller * là *, au lieu de "sur le premier' élément ' ", ce qui n'a pas beaucoup de sens. –
Tomalak
Je suis d'accord que 'libray_name' fait logiquement partie de' ', mais l'exigence actuelle est de le mettre sur le premier' '. Je vous remercie. –
MarcoS