Précédent élément en fonction d'un attribut
Bonjour,
J'ai un document XML que je dois transformer en un fichier CSV, en calculant un élément à partir des attributs existants.
Le fichier XML est le suivant :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| <?xml version="1.0" encoding="utf-8"?>
<document>
<vueObjet typePagination="N" typePage="N" ordre="1" numeroPage="NP">
<image>url_image_1</image>
</vueObjet>
<vueObjet typePagination="N" typePage="N" ordre="2" numeroPage="NP">
<image>url_image_2</image>
</vueObjet>
<vueObjet typePagination="A" typePage="N" ordre="3" numeroPage="1">
<image>url_image_3</image>
</vueObjet>
<vueObjet typePagination="N" typePage="N" ordre="4" numeroPage="NP">
<image>url_image_4</image>
</vueObjet>
<vueObjet typePagination="N" typePage="N" ordre="5" numeroPage="NP">
<image>url_image_5</image>
</vueObjet>
<vueObjet typePagination="N" typePage="N" ordre="6" numeroPage="NP">
<image>url_image_6</image>
</vueObjet>
<vueObjet typePagination="A" typePage="N" ordre="7" numeroPage="5">
<image>url_image_7</image>
</vueObjet>
<vueObjet typePagination="A" typePage="N" ordre="8" numeroPage="6">
<image>url_image_8</image>
</vueObjet>
<vueObjet typePagination="N" typePage="N" ordre="9" numeroPage="NP">
<image>url_image_9</image>
</vueObjet>
<vueObjet typePagination="N" typePage="N" ordre="10" numeroPage="NP">
<image>url_image_10</image>
</vueObjet>
</document> |
Je veux aboutir à un fichier csv comme celui-ci :
Code:
1 2 3 4 5 6 7 8 9 10 11
| Page courante Numéro Images précédentes Images suivantes Image suivante Suivante numérotée Image précédente Précédente numérotée Nom page Url
NP 1 0 9 2 3 Image 1 url_image_1
NP 2 1 8 3 3 1 Image 2 url_image_2
1 3 2 7 4 7 2 1 url_image_3
NP 4 3 6 5 7 3 3 2 url_image_4
NP 5 4 5 6 7 4 3 3 url_image_5
NP 6 5 4 7 7 5 3 4 url_image_6
5 7 6 3 8 8 6 3 5 url_image_7
6 8 7 2 9 7 7 6 url_image_8
NP 9 8 1 10 8 7 Image 9 url_image_9
NP 10 9 0 9 7 Image 10 url_image_10 |
J'ai donc fait une feuille xsl comme ceci (simplifiée ici pour faciliter la lecture) :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" media-type="text/csv" encoding="UTF-8" omit-xml-declaration="yes"/>
<xsl:param name="délimiteur"><xsl:text>	</xsl:text></xsl:param>
<xsl:param name="saut_ligne"><xsl:text>
</xsl:text></xsl:param>
<xsl:template match="/document/vueObjet">
<xsl:text>Page courante </xsl:text><xsl:value-of select="@numeroPage"/>
<xsl:value-of select="$délimiteur"/>
<xsl:text>Numéro </xsl:text><xsl:value-of select="@ordre"/>
<xsl:value-of select="$délimiteur"/>
<xsl:text> Images précédentes </xsl:text><xsl:value-of select="count(preceding::image)"/>
<xsl:value-of select="$délimiteur"/>
<xsl:text> Images suivantes </xsl:text><xsl:value-of select="count(following::image)"/>
<xsl:value-of select="$délimiteur"/>
<xsl:text> image suivante </xsl:text><xsl:value-of select="following-sibling::*[1]/@ordre"/>
<xsl:value-of select="$délimiteur"/>
<xsl:text> Suivante numérotée </xsl:text><xsl:value-of select="following-sibling::vueObjet[@typePagination != 'N']/@ordre"/>
<xsl:value-of select="$délimiteur"/>
<xsl:text> Image précédente </xsl:text><xsl:value-of select="preceding-sibling::vueObjet[1]/@ordre"/>
<xsl:value-of select="$délimiteur"/>
<xsl:text> Précédente numérotée </xsl:text><xsl:value-of select="preceding-sibling::vueObjet[1][@typePagination != 'N']/@ordre"/>
<xsl:value-of select="$délimiteur"/>
<xsl:text> Nom page </xsl:text>
<!-- TODO à déterminer avec les éléments ci-dessus -->
<xsl:choose>
<xsl:when test="true()">
<xsl:text> TODO </xsl:text>
</xsl:when>
</xsl:choose>
<xsl:value-of select="$délimiteur"/>
<xsl:text> Url </xsl:text><xsl:value-of select="image"/>
<xsl:value-of select="$saut_ligne"/>
</xsl:template>
<xsl:template match="text()">
<!-- Ignore tout le reste -->
</xsl:template>
</xsl:stylesheet> |
Je n'arrive pas à déterminer le précédent élément en fonction du type de pagination, c'est-à-dire le numéro d'ordre de la page précédente qui est numérotée (colonne "Précédente numérotée").
Ensuite, il faudra définir le nom réel de la page, mais cela devrait aller.
Quelqu'un a une idée ?
[Résolu] Précédent élément en fonction d'un attribut
Voila mon xsl final pour info.
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" media-type="text/csv" encoding="UTF-8" omit-xml-declaration="yes"/>
<xsl:param name="délimiteur"><xsl:text>	</xsl:text></xsl:param>
<xsl:param name="saut_ligne"><xsl:text>
</xsl:text></xsl:param>
<xsl:template match="/document/vueObjet">
<xsl:variable name="précédente_numérotée" select="(preceding-sibling::vueObjet[@typePagination != 'N']/@ordre)[last()]"/>
<xsl:variable name="précédente_numérotée_page" select="(preceding-sibling::vueObjet[@typePagination != 'N']/@numeroPage)[last()]"/>
<xsl:variable name="suivante_numérotée" select="(following-sibling::vueObjet[@typePagination != 'N']/@ordre)[1]"/>
<xsl:variable name="nom_page">
<xsl:choose>
<xsl:when test="@typePagination = 'A'">
<xsl:text>page </xsl:text>
<xsl:value-of select="@numeroPage"/>
</xsl:when>
<xsl:when test="@typePagination = 'N' and not($précédente_numérotée)">
<xsl:text>page non paginée, image </xsl:text>
<xsl:value-of select="@ordre"/>
</xsl:when>
<xsl:when test="@typePagination = 'N' and not($suivante_numérotée)">
<xsl:text>page non paginée, image </xsl:text>
<xsl:value-of select="@ordre"/>
</xsl:when>
<!-- Le numéro de page est déterminable avec une bonne probabilité. -->
<xsl:otherwise>
<xsl:text>page </xsl:text>
<xsl:value-of select="$précédente_numérotée_page - $précédente_numérotée + @ordre"/>
<xsl:text> (non paginée)</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:text>Numéro </xsl:text><xsl:value-of select="@ordre"/>
<xsl:value-of select="$délimiteur"/>
<xsl:text>Page </xsl:text><xsl:value-of select="@numeroPage"/>
<xsl:value-of select="$délimiteur"/>
<xsl:text>Nom réel de la page : </xsl:text>
<xsl:value-of select="$nom_page"/>
<xsl:value-of select="$saut_ligne"/>
</xsl:template>
<xsl:template match="text()">
<!-- Ignore tout le reste -->
</xsl:template>
</xsl:stylesheet> |
Citation:
Peut-être, mais ça aurait pas dû. Les outils que tu utilises, ont un bug quelque part dans la gestion de preceding-sibling::
J'utilise jEdit et Xml Copy Editor sous Linux pour tester. Le résultat est le même pour le xsl initial. C'est en changeant la structure comme ci-dessus que le problème a disparu et que la présence ou non du [last()] ne change rien.