2009-04-13 6 views
3

Comment appliquer une modification au texte dans un élément sans perdre ses éléments enfants.Comment modifier le texte d'un élément en utilisant xsl

Par exemple:

Je possède ce xml que je voudrais appliquer une modification du texte dans l'élément « p » ....

<section> 
    <p >Awesome LO</p> 
    <p > 
     Begin with an interesting fact, thought-provoking 
     <keyword>question</keyword> 
     <context> 
      <p type="Key Words Head">Banana</p> 
      <p type="Key Words">A tasty treat to eat any time, and good with ice cream – a banana split.</p> 
     </context>, or a one sentence scenario to illustrate why the learning object (content) is important. 
    </p> 
    <p > 
     Begin with a definition, if required. Then, provide an example by example view. 
    </p> 
</section> 

Alors mon xsl ressemble à ceci. ...

<xsl:template match="p"> 
    <xsl:copy> 
     <xsl:call-template name="widont-title"> 
      <xsl:with-param name="text" select="text()" /> 
     </xsl:call-template> 
    </xsl:copy> 
</xsl:template> 

le problème est que je perds le « mot-clé », « contexte », et d'autres éléments à l'intérieur du « p » quand je fais cela. Quelqu'un peut-il me diriger vers des indices? Merci!

<!-- this method puts a non breaking space in the last word of a 'p' if its less than 5 characters--> 
<xsl:template name="widont-title"> 
    <xsl:param name="temp"/> 
    <xsl:param name="text"/> 
    <xsl:param name="minWidowLength" select="5"/> 

    <xsl:choose> 
     <xsl:when test="contains($text, ' ')"> 
      <xsl:variable name="prev" select="substring-before($text,' ')"/> 
      <xsl:variable name="before" select="concat($temp,' ',$prev)"/> 
      <xsl:variable name="after" select="substring-after($text, ' ')"/> 

      <xsl:choose> 
       <xsl:when test="contains($after, ' ')"> 
        <xsl:call-template name="widont-title"> 
         <xsl:with-param name="temp" select="$before"/> 
         <xsl:with-param name="text" select="$after"/> 
        </xsl:call-template> 
       </xsl:when> 
       <xsl:when test="not(contains($after, ' ')) and string-length(translate($after,'`[email protected]#$%^\*()-_=+\\|]}[{;:,./?&lt;&gt;','')) &lt; $minWidowLength"> 

        <xsl:value-of select="concat($before, '&#160;', $after)" /> 
       </xsl:when> 
       <xsl:otherwise> 
        <xsl:value-of select="concat($before, ' ', $after)" /> 
       </xsl:otherwise> 
      </xsl:choose> 
     </xsl:when> 
     <xsl:otherwise> 
      <xsl:value-of select="$text"/> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 

Répondre

5

On ne sait pas ce que le widont-title modèle fait et si cela est correctement mis en œuvre (ressemble un peu peu trop compliqué), mais le problème est que ce modèle est trop tôt appliqué, non laissant toutes les possibilités pour les éléments enfants de p à traiter.

La solution (en utilisant le identity template et en remplaçant pour p/text() nœuds) est très simple:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes"/> 
    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="p/text()"> 
     <xsl:call-template name="widont-title"> 
      <xsl:with-param name="text" select="." /> 
     </xsl:call-template> 
    </xsl:template> 

     <!-- "widont-title" template omitted for brevity --> 

</xsl:stylesheet> 

lorsque la transformation ci-dessus est appliquée sur le document XML fourni, les enfants de tout p élément sont correctement présents dans la sortie.

Questions connexes