2013-02-27 93 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>