Xml 如何创建可重用的函数来减少大小写文本?

Xml 如何创建可重用的函数来减少大小写文本?,xml,xslt,xpath,xslt-2.0,xpath-2.0,Xml,Xslt,Xpath,Xslt 2.0,Xpath 2.0,我正在尝试创建一个函数,该函数可以降低我选择的任何文本的大小写,无论是节点的纯文本值(“UserRole”)还是属性的值(“UserRoleInfo”)。以下是示例数据: <className>UserRole</className> <!-- Want to create text userRole --> <fieldGroups> <fieldGroup name="UserRoleInfo"

我正在尝试创建一个函数,该函数可以降低我选择的任何文本的大小写,无论是节点的纯文本值(“UserRole”)还是属性的值(“UserRoleInfo”)。以下是示例数据:

<className>UserRole</className>         <!-- Want to create text userRole -->

<fieldGroups>
    <fieldGroup name="UserRoleInfo"/>   <!-- Want to create text userRoleInfo -->
</fieldGroups>
UserRole
如果您想提供解决方案,无需进一步阅读。但如果你感兴趣的话,我将尝试实现这样一个东西

在这里,我选择类名:

<xsl:apply-templates mode="lowerCaseName" select="/className"/>

在这里,我选择属性:

<xsl:apply-templates mode="printFieldGroupAssignments" select="/fieldGroups"/>

<xsl:template mode="printFieldGroupAssignments" match="fieldGroups">
    <xsl:for-each select="./fieldGroup">
        <xsl:apply-templates mode="lowerCaseName" select="./attribute::name"/>
    </xsl:for-each>
</xsl:template>

这里是我的“可重用函数”,它应该接受节点或属性

<xsl:template mode="lowerCaseName" match="node()">
    <xsl:value-of select="concat(lower-case(substring(.,1,1)), substring(.,2))"/>
</xsl:template>
<xsl:template mode="lowerCaseName" match="attribute()">
    <xsl:value-of select="concat(lower-case(substring(.,1,1)), substring(.,2))"/>
</xsl:template>

我得到以下错误:

[错误]:“attribute()”中的语法错误

[错误]:文件:Entity.xsl:第849行:分析XPath表达式“attribute()”时出错

所以我将attribute()改为text()


我得到以下错误:

[错误]:无法编译样式表

[致命]:错误检查表达式“funcall(小写,[funcall(子字符串,[cast(变量ref(entityClassName/节点集)、字符串)、cast(int-expr(1)、real)、cast(int-expr(1)、real)])]”的类型

我认为我的问题在于我不理解节点、节点集和纯文本之间的区别

我下一步该怎么解决这个问题?我是否应该放弃,用不同的方法重新开始?欢迎所有建议

我想我的问题是我不理解其中的区别 在节点、节点集和纯文本之间

这些是重要的区别。依我看,这里还有两个可能更相关:(1)函数与命名模板,(2)应用模板与调用模板

Re#1,您说您想创建一个函数,但您正在编写模板。
Re#2,您正在使用mode应用模板,您应该在其中调用命名模板

要使用命名模板执行此操作,您需要定义一个模板,例如:

<xsl:template name="lowerFirst">
    <xsl:param name="text"/>
    <xsl:value-of select="concat(lower-case(substring($text, 1, 1)), substring($text, 2))"/>
</xsl:template>

然后根据需要打电话。例如,给定以下测试输入:

<root>
    <anything>AnyThing</anything>
    <!-- leave as is -->

    <className name="TestCase">UserRole</className>
    <!-- Want to create text userRole -->

    <fieldGroups>
        <fieldGroup name="UserRoleInfo"/>
        <!-- Want to create text userRoleInfo -->
    </fieldGroups>
</root>

任何东西
用户角色
您可以使用以下样式表:

XSLT2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template name="lowerFirst">
    <xsl:param name="text"/>
    <xsl:value-of select="concat(lower-case(substring($text, 1, 1)), substring($text, 2))"/>
</xsl:template>

<xsl:template match="className">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:call-template name="lowerFirst">
            <xsl:with-param name="text" select="."/>
        </xsl:call-template>
    </xsl:copy>
</xsl:template>

<xsl:template match="fieldGroup/@name">
    <xsl:attribute name="name">
        <xsl:call-template name="lowerFirst">
            <xsl:with-param name="text" select="."/>
        </xsl:call-template>
    </xsl:attribute>
</xsl:template>

</xsl:stylesheet>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="http://www.example.com/my"
exclude-result-prefixes="my">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:function name="my:lowerFirst">
    <xsl:param name="text"/> 
    <xsl:value-of select="concat(lower-case(substring($text, 1, 1)), substring($text, 2))"/>
</xsl:function>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="className">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:value-of select="my:lowerFirst(.)"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="fieldGroup/@name">
    <xsl:attribute name="name">
        <xsl:value-of select="my:lowerFirst(.)"/>
    </xsl:attribute>
</xsl:template>

</xsl:stylesheet>

获得:

<?xml version="1.0" encoding="UTF-8"?>
<root>
      <anything>AnyThing</anything>
   <!-- leave as is -->

    <className name="TestCase">userRole</className>
   <!-- Want to create text userRole -->

    <fieldGroups>
            <fieldGroup name="userRoleInfo"/>
      <!-- Want to create text userRoleInfo -->
    </fieldGroups>
</root>

任何东西
用户角色
--
在XSLT 2.0中,您可以创建自己的函数并使用它来代替命名模板,例如:

XSLT2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template name="lowerFirst">
    <xsl:param name="text"/>
    <xsl:value-of select="concat(lower-case(substring($text, 1, 1)), substring($text, 2))"/>
</xsl:template>

<xsl:template match="className">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:call-template name="lowerFirst">
            <xsl:with-param name="text" select="."/>
        </xsl:call-template>
    </xsl:copy>
</xsl:template>

<xsl:template match="fieldGroup/@name">
    <xsl:attribute name="name">
        <xsl:call-template name="lowerFirst">
            <xsl:with-param name="text" select="."/>
        </xsl:call-template>
    </xsl:attribute>
</xsl:template>

</xsl:stylesheet>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="http://www.example.com/my"
exclude-result-prefixes="my">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:function name="my:lowerFirst">
    <xsl:param name="text"/> 
    <xsl:value-of select="concat(lower-case(substring($text, 1, 1)), substring($text, 2))"/>
</xsl:function>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="className">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:value-of select="my:lowerFirst(.)"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="fieldGroup/@name">
    <xsl:attribute name="name">
        <xsl:value-of select="my:lowerFirst(.)"/>
    </xsl:attribute>
</xsl:template>

</xsl:stylesheet>

我想我的问题是我不理解其中的区别 在节点、节点集和纯文本之间

这些是重要的区别。依我看,这里还有两个可能更相关:(1)函数与命名模板,(2)应用模板与调用模板

Re#1,您说您想创建一个函数,但您正在编写模板。
Re#2,您正在使用mode应用模板,您应该在其中调用命名模板

要使用命名模板执行此操作,您需要定义一个模板,例如:

<xsl:template name="lowerFirst">
    <xsl:param name="text"/>
    <xsl:value-of select="concat(lower-case(substring($text, 1, 1)), substring($text, 2))"/>
</xsl:template>

然后根据需要打电话。例如,给定以下测试输入:

<root>
    <anything>AnyThing</anything>
    <!-- leave as is -->

    <className name="TestCase">UserRole</className>
    <!-- Want to create text userRole -->

    <fieldGroups>
        <fieldGroup name="UserRoleInfo"/>
        <!-- Want to create text userRoleInfo -->
    </fieldGroups>
</root>

任何东西
用户角色
您可以使用以下样式表:

XSLT2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template name="lowerFirst">
    <xsl:param name="text"/>
    <xsl:value-of select="concat(lower-case(substring($text, 1, 1)), substring($text, 2))"/>
</xsl:template>

<xsl:template match="className">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:call-template name="lowerFirst">
            <xsl:with-param name="text" select="."/>
        </xsl:call-template>
    </xsl:copy>
</xsl:template>

<xsl:template match="fieldGroup/@name">
    <xsl:attribute name="name">
        <xsl:call-template name="lowerFirst">
            <xsl:with-param name="text" select="."/>
        </xsl:call-template>
    </xsl:attribute>
</xsl:template>

</xsl:stylesheet>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="http://www.example.com/my"
exclude-result-prefixes="my">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:function name="my:lowerFirst">
    <xsl:param name="text"/> 
    <xsl:value-of select="concat(lower-case(substring($text, 1, 1)), substring($text, 2))"/>
</xsl:function>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="className">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:value-of select="my:lowerFirst(.)"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="fieldGroup/@name">
    <xsl:attribute name="name">
        <xsl:value-of select="my:lowerFirst(.)"/>
    </xsl:attribute>
</xsl:template>

</xsl:stylesheet>

获得:

<?xml version="1.0" encoding="UTF-8"?>
<root>
      <anything>AnyThing</anything>
   <!-- leave as is -->

    <className name="TestCase">userRole</className>
   <!-- Want to create text userRole -->

    <fieldGroups>
            <fieldGroup name="userRoleInfo"/>
      <!-- Want to create text userRoleInfo -->
    </fieldGroups>
</root>

任何东西
用户角色
--
在XSLT 2.0中,您可以创建自己的函数并使用它来代替命名模板,例如:

XSLT2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template name="lowerFirst">
    <xsl:param name="text"/>
    <xsl:value-of select="concat(lower-case(substring($text, 1, 1)), substring($text, 2))"/>
</xsl:template>

<xsl:template match="className">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:call-template name="lowerFirst">
            <xsl:with-param name="text" select="."/>
        </xsl:call-template>
    </xsl:copy>
</xsl:template>

<xsl:template match="fieldGroup/@name">
    <xsl:attribute name="name">
        <xsl:call-template name="lowerFirst">
            <xsl:with-param name="text" select="."/>
        </xsl:call-template>
    </xsl:attribute>
</xsl:template>

</xsl:stylesheet>
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="http://www.example.com/my"
exclude-result-prefixes="my">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:function name="my:lowerFirst">
    <xsl:param name="text"/> 
    <xsl:value-of select="concat(lower-case(substring($text, 1, 1)), substring($text, 2))"/>
</xsl:function>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="className">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:value-of select="my:lowerFirst(.)"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="fieldGroup/@name">
    <xsl:attribute name="name">
        <xsl:value-of select="my:lowerFirst(.)"/>
    </xsl:attribute>
</xsl:template>

</xsl:stylesheet>

您已经编写了match=“attribute()”。如果要匹配任何属性,通常的方法是
match=“@*”
,但如果愿意,也可以(在2.0中)编写
match=“attribute(*)”
。如错误消息所示,不允许使用您的语法

这只是对其他人给你的好答案的一个小补充。

你已经编写了match=“attribute()”。如果要匹配任何属性,通常的方法是
match=“@*”
,但如果愿意,也可以(在2.0中)编写
match=“attribute(*)”
。如错误消息所示,不允许使用您的语法


这只是对其他人给您的好答案的一个小补充。

XSLT2.0允许将
编写为
@michael。您的两个示例的输出都是
AnyThinguserRole
。我看不出它在改变用户角色信息。它不会产生上面列出的输出。@michael
xmlns:my=”http://www.example.com/my“
给出“URI未注册”的错误,它告诉我添加架构或DTD。@michael什么是
排除结果前缀=“my”
do?@PatrickGarner似乎是“无框架的”XSLT Fiddle上的处理器运行不正常。使用Saxon进行尝试,可以在那里和网站上获得:XSLT2.0允许将
编写为
@michael。两个示例的输出都是
AnyThinguserRole
。我看不出它在改变用户角色信息。它不会产生上面列出的输出。@michael
xmlns:my=”http://www.example.com/my“
给出“URI未注册”的错误,它告诉我添加架构或DTD。@michael什么是
排除结果前缀=“my”
do?@PatrickGarner似乎是“无框架的”XSLT Fiddle上的处理器运行不正常。使用Saxon进行尝试,这两种方法都有