使用xsl 2.0我试图将所有大写文本转换为每个节点只有大写字母的第一个字母。他们是很多可能的儿童元素。
<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>
如何在头部的所有子节点中进行小写转换?
答案 0 :(得分:4)
此转换产生划分单词的标点符号的结果:
<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>
<强>解释强>:
正确使用<xsl:analyze-string>
指令。
正确使用\p{L}
字符类。
正确使用<xsl:matching-substring>
和<xsl:non-matching-substring>
说明。
答案 1 :(得分: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>
答案 2 :(得分: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>
答案 3 :(得分: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>
虽然不确定第三个“BLAH”,但是这个text()节点以空格开头,因此在使兄弟文本节点大写正确时会有一些增加的难度。取消注释“x”元素以查看此内容。您可能还想查看规范化空格和position()函数以进一步了解。