Forum Programmation.autre XSL : filtre sur les petits fils

Posté par  .
Étiquettes : aucune
0
21
déc.
2009

Bonjour à tous,

je possède un fichier xml du type :



[?xml version="1.0" encoding="utf-8"?]
[A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"]
[B1]
[C1]xx[/C1]
[C2]yy[/C2]
[/B1]
[B2]
[C3]dsfhizu[/C3]
[C4]
[D1]zoibvd[/D1]
[D2]0[/D2]
[/C4]
[/B2]
[B2]
[C3]ii[/C3]
[C4]
[D1]fazoifbvza[/D1]
[D2]0[/D2]
[/C4]
[/B2]
[B2]
[C3]mliohszaz[/C3]
[C4]
[D1]cvkjbsdhzpz[/D1]
[D2]1[/D2]
[/C4]
[/B2]
[/A]


Et je souhaiterais enlever tous les éléments B2 pour lesquels la balise D2 est à 1, et garder le reste des informations identiques.

J'ai un peu de mal à trouver la syntaxe XSL correspondante. J'ai bien essayé ça :


[xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"]
[xsl:output method="xml" indent="yes"/]
[xsl:strip-space elements="*"/]
[xsl:template match="/"]
[xsl:element name="A"]
[xsl:for-each select="/A/B1"]
[xsl:copy-of select="."/]
[/xsl:for-each]
[xsl:for-each select="/A/B2[C4/D2=0]"]
[xsl:copy-of select="."/]
[/xsl:for-each]
[/xsl:element]
[/xsl:template]
[/xsl:stylesheet]

Mais le namespace, au lieu de se placer au niveau de A, se retrouve ventilé sur tous les éléments B1 et B2...

Si quelqu'un a une idée...
Merci d'avance !
  • # J'espère que c'est pas tes devoirs

    Posté par  . Évalué à 2.



    [xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"]
    [xsl:output method="xml" indent="yes"/]

    [xsl:template match="/A"]
    [xsl:element name="A"]
    [xsl:apply-templates select="./*"/]
    [/xsl:element]
    [/xsl:template]

    [xsl:template match="B2"]
    [xsl:if test="number(./C4/D2) < 1"]
    [xsl:element name="B2"]
    [xsl:copy-of select="./*"/]
    [/xsl:element]
    [/xsl:if]
    [/xsl:template]

    [/xsl:stylesheet]

    • [^] # oups

      Posté par  . Évalué à 2.

      oups mauvais fichier.



      [xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"]
      [xsl:output method="xml" indent="yes"/]

      [xsl:template match="/A"]
      [xsl:element name="{name()}"]
      [xsl:copy-of select="./B2[number(C4/D2)<1]" copy-namespaces="no"/]
      [/xsl:element]
      [/xsl:template]

      [/xsl:stylesheet]



      Mais ne passera pas avec libxml. (xslt 1.0)
      • [^] # Re: oups

        Posté par  . Évalué à 1.

        Merci pour ta réponse !

        Ton fichier se comporte comme celui que j'ai indiqué, sauf qu'il ne préserve pas les éléments B1, et que j'ai toujours les namespaces sur B2 au lieu de les avoir sur A ! Peut-être que mon moteur XSLT ne se comporte pas bien (j'utilise Editix) ?
        • [^] # Re: oups

          Posté par  . Évalué à 2.

          Un oubli
          suffit de changer

          [xsl:for-each select="/A/B2[C4/D2=0]"]

          en

          [xsl:for-each select="/A/B2[C4/D2=0] /A/B1"]

          et t'auras les B1 avec
        • [^] # Re: oups

          Posté par  . Évalué à 2.

          j'ai toujours les namespaces sur B2 au lieu de les avoir sur A !
          Comme mentionné, faut du xslt 2.0
          Mais tu peux tjs forcer le namespace sur A


          [xsl:element name="{name()}" namespace="{namespace-uri()}"]
  • # Toujours pas...

    Posté par  . Évalué à 1.

    Merci pour ces nouvelles suggestions. En effet en XSL 2.0 on peut grouper les sélecteurs comme tu le suggères. J'ai donc pu simplifier mon fichier comme suit :
    [xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"]
    [xsl:output method="xml" indent="yes"/]
    [xsl:strip-space elements="*"/]
    [xsl:template match="/"]
      [xsl:element name="A" namespace="http://www.w3.org/2001/XMLSchema-instance"]
      [xsl:for-each select="(/A/B1 | /A/B2[C4/D2=0])"]
        [xsl:copy-of select="."/]
      [/xsl:for-each]
      [/xsl:element]
    [/xsl:template]
    [/xsl:stylesheet]
    
    Le problème est que même lorsque je force le ns dans A avec
    namespace="http://www.w3.org/2001/XMLSchema-instance"
    je me retrouve avec un ns pour A et des ns sur les B1et les B2. Il semble que le moteur ne teste pas l'égalité entre ces ns :'o( Je vais finir par croire que je n'ai pas d'autre choix que de me taper tous les tags à la main en template (ce sont les copy-of qui introduisent les namespaces).
    • [^] # Re: Toujours pas...

      Posté par  . Évalué à 1.

      De guerre lasse et quitte à faire un truc crado (cf les dizaines de templates envisagés ci-dessus), je pense que je vais virer le namespace dans le fichier source, faire la transfo avec le fichier 2.0 simplifié et le remettre après. Testé à la main, c'est pas propre mais ça marche nickel !

      Merci et A+

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.