Xslt 使用两个分隔符将第一个字符串字母转换为大写,其余字母转换为小写
我开始学习XSLT,在编写XSLT函数以在XSLT中从小写转换为大写以及从大写转换为小写时遇到了一些困难 通过编写不同的xslt函数,我做了很多尝试,但我认为我在代码中犯了一些错误Xslt 使用两个分隔符将第一个字符串字母转换为大写,其余字母转换为小写,xslt,xslt-1.0,Xslt,Xslt 1.0,我开始学习XSLT,在编写XSLT函数以在XSLT中从小写转换为大写以及从大写转换为小写时遇到了一些困难 通过编写不同的xslt函数,我做了很多尝试,但我认为我在代码中犯了一些错误 <xsl:template name="ConvertXmlStyleToCamelCase"> <xsl:param name="occupation"/> <xsl:template match="node()"/> <xsl:variable
<xsl:template name="ConvertXmlStyleToCamelCase">
<xsl:param name="occupation"/>
<xsl:template match="node()"/>
<xsl:variable name="uppercase" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'" />
<xsl:variable name="lowercase" select="'abcdefghijklmnopqrstuvwxyz'" />
<xsl:param name="delimiter" select='/'/>
<xsl:param name="delimiter2" select= "' '"/>
<xsl:if test="not($occupation = '')" >
<xsl:choose>
<xsl:when test="contains($occupation, $delimiter)">
<xsl:variable name="word" select="substring-before(concat($occupation, $delimiter), $delimiter)"></xsl:variable>
<xsl:if test="$word">
<xsl:value-of select="translate(substring($word, 1, 1), $lowercase, $uppercase)"/>
<xsl:value-of select="translate(substring($word,2), $uppercase, $lowercase)"/>
</xsl:if>
</xsl:when>
<xsl:when test="contains( $occupation, $delimiter)">
<xsl:value-of select="$delimiter"/>
<!-- Recursive call to template to translate the text after delimeter -->
<xsl:call-template name="ConvertXmlStyleToCamelCase">
<xsl:with-param name="occupation" select="substring-after($occupation, $delimiter)"/>
</xsl:call-template>
</xsl:when>
<xsl:when test="contains($occupation, $delimiter2)">
<xsl:variable name="word2" select="substring-before(concat($occupation, $delimiter2), $delimiter2)"></xsl:variable>
<xsl:if test="$word2">
<xsl:value-of select="translate(substring($word2, 1, 1), $lowercase, $uppercase)"></xsl:value-of>
<xsl:value-of select="translate(substring($word2, 2), $uppercase, $lowercase)"/>
</xsl:if>
</xsl:when>
<xsl:when test="contains($occupation, $delimiter2)">
<xsl:value-of select="$delimiter2"/>
<!-- Recursive call to template to translate the text after delimeter2 -->
<xsl:call-template name="ConvertXmlStyleToCamelCase">
<xsl:with-param name="occupation" select="substring-after($occupation, $delimiter2)"/>
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:if>
<xsl:if test="not($occupation = $delimiter and $delimiter2)">
<xsl:value-of select="substring(occupation, 1, 1)"/>
<xsl:value-of select="translate(substring(occupation, 2), $uppercase, $lowercase)"/>
</xsl:if>
</xsl:template>
输入将是下面的任意一个值
1.自营职业者
2.技能贸易
3.政府
预期产出如下
正如我在评论中提到的,您的代码是不可复制的。从您报告的结果可以清楚地看出,您的第二个分隔符没有被应用。在AICT中,这是因为您首先检查第一个分隔符是否存在——如果您找到了它,您就不必费心在第一个分隔符之前测试第二个分隔符是否存在 考虑以下示例(改编自): XML
<input>
<item>Self/Employed</item>
<item>Skill Trade</item>
<item>Government</item>
<item>a combi/na/tion of various de/limi/ters</item>
</input>
自雇人士
技能贸易
政府
各种设计/限制的组合/说明
XSLT1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/input">
<output>
<xsl:for-each select="item">
<caps>
<xsl:call-template name="capitalize">
<xsl:with-param name="text" select="."/>
</xsl:call-template>
</caps>
</xsl:for-each>
</output>
</xsl:template>
<xsl:template name="capitalize">
<xsl:param name="text"/>
<xsl:param name="delimiter" select="' '"/>
<xsl:variable name="upper-case" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:variable name="lower-case" select="'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:variable name="word" select="substring-before(concat($text, $delimiter), $delimiter)" />
<xsl:choose>
<xsl:when test="$delimiter=' '">
<!-- tokenize word by 2nd delimiter -->
<xsl:call-template name="capitalize">
<xsl:with-param name="text" select="$word"/>
<xsl:with-param name="delimiter" select="'/'"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<!-- capitalize word -->
<xsl:value-of select="translate(substring($word, 1, 1), $lower-case, $upper-case)"/>
<xsl:value-of select="translate(substring($word, 2), $upper-case, $lower-case)"/>
</xsl:otherwise>
</xsl:choose>
<xsl:if test="contains($text, $delimiter)">
<xsl:value-of select="$delimiter"/>
<!-- recursive call -->
<xsl:call-template name="capitalize">
<xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
<xsl:with-param name="delimiter" select="$delimiter"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
结果
<?xml version="1.0" encoding="UTF-8"?>
<output>
<caps>Self/Employed</caps>
<caps>Skill Trade</caps>
<caps>Government</caps>
<caps>A Combi/Na/Tion Of Various De/Limi/Ters</caps>
</output>
自雇人士
技能贸易
政府
各种设计/限制的组合/说明
将来是否可以有两个以上的分隔符?如果是这样,请尝试使用此XSLT,它可以很容易地扩展为具有更多(单字符)分隔符。只需更改ConvertXmlStyleToCamelCase
模板中的分隔符
参数
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="item">
<item>
<xsl:call-template name="ConvertXmlStyleToCamelCase" />
</item>
</xsl:template>
<xsl:template name="ConvertXmlStyleToCamelCase">
<xsl:param name="text" select="."/>
<xsl:param name="delimiters" select="' /'"/>
<xsl:variable name="upper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:variable name="lower" select="'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:variable name="nextDelimiter" select="substring(translate($text, translate($text, $delimiters, ''), ''), 1, 1)" />
<xsl:variable name="string" select="substring-before(concat($text, ' '), substring(concat($nextDelimiter, ' '), 1, 1))" />
<xsl:message terminate="no">Next delimiter is <xsl:value-of select="$nextDelimiter" /></xsl:message>
<xsl:value-of select="translate(substring($string, 1, 1), $lower, $upper)"/>
<xsl:value-of select="translate(substring($string, 2), $upper, $lower)"/>
<xsl:if test="$nextDelimiter">
<xsl:value-of select="$nextDelimiter" />
<xsl:call-template name="ConvertXmlStyleToCamelCase">
<xsl:with-param name="text" select="substring-after($text, $nextDelimiter)"/>
<xsl:with-param name="delimiters" select="$delimiters"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
下一个分隔符是
在我使用第三个分隔符作为示例的地方查看它的实际操作
对于双重转换,其目的是查找字符串中的下一个分隔符。要做到这一点(在XSLT1.0中),您需要删除所有非分隔符的字符。执行
translate($text,$delimiters,”)
将删除所有分隔符,并返回所有非分隔符的字符。如果将此结果应用于原始字符串,则只剩下分隔符。第一个字符将成为下一个分隔符。一个模板不能包含另一个模板-因此您报告的结果不能是。您确定要使用XSLT 1.0版吗?对于这样的操作来说,这是非常有限的。@Kay它的遗留系统现在的要求都在这上面。首先非常感谢您的快速响应,真的很感激!!!您是对的,先生,不应该有两个模板,我只是盲目地从堆栈溢出函数中读取,并在本地测试:)1问题:从xml中,只有一个值作为输入,它可以是我提到的上述三种格式中的任意一种,所以我评论了match template调用大写模板,如下所示2.很想知道你为什么写3。如果值为空,xslt抛出的任何运行时错误都会发生什么情况,因为我们没有保留任何检查null或空“”的条件。@nick我想你可以自己回答这些问题。试图理解你的代码,请在这里帮助我,您在模板中声明,如果我输入$text=skilleed TRADE,然后word=skilleed,然后它通过,它调用模板并将delimeter值更改为“/”,现在在choose块中,当条件失败时,它将单词大写为skilleed,现在给定的文本是skilleed TRADE,它将不会通过此条件,因为delimeter值重写为“/”几乎是正确的。第一个单词是熟练的,这是传递到模板的新$text,以及作为参数的/
。由于此文本不包含参数,因此处理到此结束。第二个字在末尾使用递归调用传回。HTH.感谢您的回复,以明确说明问题。例如,如果我将输入作为熟练/人工传递nextdelimeter=''的值,如果它是正确的,那么我们可以简单地执行string=“substring before($text,nextdelimeter)”然后string=SKILLED,它将修改为熟练。另一个词也会采用类似的方式。忽略我的第一条评论,因为我是XSLT新手,试图了解我是否以熟练/劳动1的身份提供输入。translate($text,$delimiters,'')=SKILLEDLABOR 2。translate($text,translate($text,$delimiters,),'')=(熟练/劳动,熟练劳动力,'')我们得到了什么输出?is/or SKILLEDLABOR您能给我详细的解释吗?您能插入xsl:message以输出nextdelimeter的值和字符串吗?我想打印日志中的值我不确定语法是否正确。我已经扩展了我的答案来解释双重翻译,并添加了一个