Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Xslt 使用两个分隔符将第一个字符串字母转换为大写,其余字母转换为小写_Xslt_Xslt 1.0 - Fatal编程技术网

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

我开始学习XSLT,在编写XSLT函数以在XSLT中从小写转换为大写以及从大写转换为小写时遇到了一些困难

通过编写不同的xslt函数,我做了很多尝试,但我认为我在代码中犯了一些错误

<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的值和字符串吗?我想打印日志中的值我不确定语法是否正确。我已经扩展了我的答案来解释双重翻译,并添加了一个