2009-04-13 25 views
3

如何對元素中的文本應用更改而不丟失其子元素。如何使用xsl更改元素中的文本

例如:

我有這樣的XML,我想申請變更爲「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> 

所以我的XSL是這樣的。 ...

<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> 

問題是,當我這樣做時,我失去了「關鍵字」,「上下文」和其他元素。任何人都可以指出我的線索嗎?謝謝!

<!-- 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> 

回答

5

目前尚不清楚該widont-title模板做什麼以及是否被正確執行(看起來有點位太複雜),但問題是,這個模板是太很快應用,不留下p的子元素的任何可能性被處理。

的溶液(使用identity template並覆蓋它p/text()節點)是非常簡單的

<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> 

當上述變換所提供的XML文檔施加的任何的兒童p元素正確出現在輸出中。

相關問題