2013-02-27 56 views
3

使用xsl 2.0我試圖將所有大寫文本轉換爲只有每個節點大寫字母的第一個字母。他們有很多可能的孩子元素。在xsl中將節點和子節點中的文本轉換爲小寫

<text> text text text 
<head>BLAH <unkownTag>BLAH</unkownTag> BLAH </head> 
</text> 

我想改變這個閱讀

<text> text text text 
<head>Blah <unkownTag>Blah</unkownTag> Blah </head> 
</text> 

我來最接近的是

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="@*|node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
    </xsl:copy> 
</xsl:template> 
<xsl:template match="head/text()"> 
    <xsl:value-of select="concat(upper-case(substring(.,1,1)),lower-case(substring(.,2)))"/>   
</xsl:template> 

這給了我結果

<text> text text text 
    <head>Blah <unkownTag>BLAH</unkownTag> blah </head> 
</text> 

我怎樣才能得到小寫轉換髮生在所有的頭的孩子節點?

回答

4

該變換產生標點符號的通緝的結果regardles定界的話:

<xsl:stylesheet version="2.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="head//text()"> 
    <xsl:analyze-string select="." regex="\p{{L}}+"> 
    <xsl:matching-substring> 
    <xsl:value-of select= 
     "concat(upper-case(substring(.,1,1)), lower-case(substring(.,2)))"/> 
    </xsl:matching-substring> 
    <xsl:non-matching-substring> 
    <xsl:value-of select="."/> 
    </xsl:non-matching-substring> 
    </xsl:analyze-string> 
</xsl:template> 
</xsl:stylesheet> 

當所提供的XML文檔應用:

<text> text text text 
<head>BLAH <unkownTag>BLAH</unkownTag> BLAH </head> 
</text> 

的想要得到正確的結果:

<text> text text text 
<head>Blah <unkownTag>Blah</unkownTag> Blah </head> 
</text> 

當該XML文檔上施加:

<text> text text text 
<head>BLAH$<unkownTag>BLAH</unkownTag>-BLAH;</head> 
</text> 

再次正確的結果產生:

<text> text text text 
<head>Blah$<unkownTag>Blah</unkownTag>-Blah;</head> 
</text> 

說明

  1. 正確使用<xsl:analyze-string>指令。

  2. 正確使用\p{L}字符類。

  3. 正確使用<xsl:matching-substring><xsl:non-matching-substring>說明。

0

試試這個。我沒有測試過,你可能需要稍微調整一下。

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

<xsl:template match="head"> 
    <xsl:copy> 
    <xsl:apply-templates select="@*|node()"> 
     <xsl:value-of select="concat(upper-case(substring(.,1,1)),lower-case(substring(.,2)))"/> 
    </xsl:apply-templates> 
    </xsl:copy> 
</xsl:template> 
+1

不幸的是,它看起來不像中的。 – user1748728 2013-02-27 01:38:46

0

這可能會幫助您獲得部分方法。

<xsl:template match="/"> 
    <xsl:apply-templates select="node()" mode="firstup"/> 
</xsl:template> 

<xsl:template match="text()" mode="firstup"> 
    <!--<x>--> 
    <xsl:value-of select="concat(upper-case(substring(.,1,1)),lower-case(substring(.,2)))"/> 
    <!--</x>--> 
</xsl:template> 

不知道的第三個「嗒嗒」的是,這個文本()節點以空格開始,所以會有在獲得同級文本節點資本糾正一些難度增加。取消註釋「x」元素以查看此內容。您可能還想查看空間標準化和position()函數以獲得更多信息。

1

文字中的空格使這成爲一個有趣的問題。要匹配'head'下的所有text()節點,請使用XPath表達式來查看祖先。

在這裏,我標記字符串,然後遍歷結果集,將第一個字符更改爲大寫,將後面的字符更改爲小寫。

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="text()[ ancestor::head ]"> 
     <xsl:value-of select=" 
      for $str in tokenize(., '\s') 
      return concat(upper-case(substring($str,1,1)), 
          lower-case(substring($str,2)))"/> 
    </xsl:template> 
</xsl:stylesheet>