这是一个单一的 XPath 2.0 表达式,它以所需的方式处理带引号和不带引号的字符串的任何混合 - 以任何顺序:
string-join(
(for $str in tokenize(replace(., "(.*?)("".*?"")([^""]*)", "|$1|$2|$3|", "x"),"\|")
return
if(not(contains($str, """")))
then lower-case($str)
else $str
),
"")
为了进行全面测试,我在以下 XML 文档上评估上述表达式:
<node>Some "Text""and Some" More "Text" XXX "Even More"</node>
产生了想要的正确结果:
some "Text""and Some" more "Text" xxx "Even More"
XSLT 2.0 验证:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:sequence select=
'string-join(
(for $str in tokenize(replace(., "(.*?)("".*?"")([^""]*)", "|$1|$2|$3|", "x"),"\|")
return
if(not(contains($str, """")))
then lower-case($str)
else $str
),
"")
'/>
</xsl:template>
</xsl:stylesheet>
当对上述 XML 文档应用此转换时,将评估 XPath 表达式,并将此评估的结果复制到输出:
some "Text""and Some" more "Text" xxx "Even More"
最后,一个 XSLT 2.0 解决方案——更容易编写和理解:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<xsl:analyze-string select="." regex='".*?"'>
<xsl:non-matching-substring>
<xsl:sequence select="lower-case(.)"/>
</xsl:non-matching-substring>
<xsl:matching-substring><xsl:sequence select="."/></xsl:matching-substring>
</xsl:analyze-string>
</xsl:template>
</xsl:stylesheet>