2 votes

Est-il possible de rendre xsl:template sensible au noeud pushed-from sans utiliser xsl:param ?

Je suis presque sûr que la réponse à cette question est non, mais comme la seule alternative est ce que je considère comme un code inélégant, j'ai pensé que je devais lancer cette question et voir si quelque chose me manque, tout en espérant que cela n'a pas été demandé.

Étant donné cette source XML :

<root>
    <p>Hello world</p>
    <move elem="content" item="test"/>
    <p>Another text node.</p>
    <content item="test">I can't <b>figure</b> this out.</content>
</root>

Je veux ce résultat :

<root>
    <block>Hello world</block>
    <newContent>I can't <hmmm>figure</hmmm> this out.</newContent>
    <block>Another text node.</block>
</root>

Une description en langage ordinaire :

  1. Remplacer <move .../> par le résultat du traitement l'élément dont le nom correspond à l'attribut @elem de move et dont l'@item correspond à l'attribut @item de move (par exemple, dans ce cas, le contenu de l'élément [<content>] est traité de sorte que <b>est remplacé par <hmm>).
  2. Empêcher l'élément de l'étape 1 de soit écrit dans l'arbre de résultats dans son ordre original de document.

Le problème est que le document XML d'entrée sera considérablement plus complexe et variable. Et la feuille de style est un transformateur tiers que je développe. Le modèle que je devrais copier afin d'utiliser une solution basée sur le mode est d'une taille assez importante et cela me semble inélégant. Je sais, par exemple, que ceci pourrait fonctionner :

<xsl:template match="b">
    <hmmm>
        <xsl:apply-templates/>
    </hmmm>
</xsl:template>
<xsl:template match="p">
    <block>
        <xsl:apply-templates/>
    </block>
</xsl:template>
<xsl:template match="move">
    <xsl:variable name="elem" select="@elem"/>
    <xsl:variable name="item" select="@item"/>
    <xsl:apply-templates select="//*[name()=$elem and @item=$item]" mode="copy-and-process"/>
</xsl:template>
<xsl:template match="content"/>
<xsl:template match="content" mode="copy-and-process">
            <newContent><xsl:apply-templates/></newContent>
</xsl:template>

Ce que je voudrais faire, c'est que le <xsl:template> qui correspond à "content" soit sensible à ce que le nœud lui pousse. Ainsi, je peux avoir un <xsl:template match="content"/> qui n'est exécuté (et donc son nœud correspondant et ses enfants sont supprimés) que lorsque le nœud poussé est <Root> et non <move>. La vertu de cette méthode est que si le modèle pertinent de la feuille de style tierce est mis à jour, je n'ai pas à me soucier de mettre à jour une copie de la feuille de style qui traite le nœud <content>. Je suis presque sûr que ce n'est pas possible, mais j'ai pensé que cela valait la peine de poser la question.

1voto

Dimitre Novatchev Points 147842

Faites simplement :

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:key name="kMover" match="move" use="concat(@elem,'+',@item)"/>

 <xsl:key name="kToMove" match="*" use="concat(name(),'+',@item)"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="move">
  <newContent>
      <xsl:apply-templates mode="move" select=
       "key('kToMove', concat(@elem,'+',@item))/node()"/>
  </newContent>
 </xsl:template>

 <xsl:template match="p">
  <block><xsl:apply-templates/></block>
 </xsl:template>

 <xsl:template match="b" mode="move">
  <hmmm><xsl:apply-templates/></hmmm>
 </xsl:template>
 <xsl:template match="*[key('kMover', concat(name(),'+',@item))]"/>
</xsl:stylesheet>

Lorsque cette transformation est appliquée sur le document XML fourni :

<root>
    <p>Hello world</p>
    <move elem="content" item="test"/>
    <p>Another text node.</p>
    <content item="test">I can't <b>figure</b> this out.</content>
</root>

le résultat voulu et correct est produit :

<root>
   <block>Hello world</block>
   <newContent>I can't <hmmm>figure</hmmm> this out.</newContent>
   <block>Another text node.</block>
</root>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X