XSLT:我可以创建一个自己作为模板的函数库吗?

迈阿密滩

我有几个XSLT转换。它们都包含相同的模板,看起来像这样(其实现和功能无关紧要):

<xsl:template match="firstField| secondField | thirdField">
    <xsl:element name="{local-name(.)}">    
    <xsl:choose>
        <xsl:when test="string-length(.)!=0"><xsl:value-of select="."/></xsl:when>  
        <xsl:otherwise>ABSENT</xsl:otherwise>   
    </xsl:choose>   
    </xsl:element>
</xsl:template>

如您所见,我列出了要在模板匹配中应用的模板的字段。

但实际上,我想在所有转换中都使用此模板,但是当然要使用不同的字段名称。换句话说,我想像将其用作函数一样使用它,我可以将其插入任何.xsl文件并指定参数列表,这些参数是要通过这种方式修改的字段的名称。

我可以用XSLT做到吗?

亚伯

更新,我可能误解了您的问题,并再次查看了您的模板(有关解决方案说明的更一般的描述,请参见下文)。

你写了:

<xsl:template match="firstField| secondField | thirdField">
    <xsl:element name="{local-name(.)}">    
    <xsl:choose>
        <xsl:when test="string-length(.)!=0"><xsl:value-of select="."/></xsl:when>  
        <xsl:otherwise>ABSENT</xsl:otherwise>   
    </xsl:choose>   
    </xsl:element>
</xsl:template>

和:

我想像将其用作函数一样使用它,我可以将其插入任何.xsl文件并指定参数列表,这些参数是通过这种方式修改的字段的名称。

如果用“这样”的意思是说:

  • 将本地名称用作新的元素名称(即,我假设您故意选择从名称空间中剥离它,否则xsl:copy就足够了)
  • 如果元素的内容为空,则输出“ ABSENT”
  • 否则,取当前节点的值

然后,您可以按照以下方式进行操作。但这仅在您的要求像您所说的那样普遍适用于您的用例时才有效。

编写如下模板:

<xsl:variable name="names">
    <names>
        <n>firstField</n>
        <n>secondField</n>
        <n>thirdField</n>
    </names>
</xsl:variable>

<xsl:template match="*" mode="by-name">
   <xsl:element name="{local-name(.)}">
      <xsl:apply-templates select="self::node()" mode="text" />
   </xsl:element>
</xsl:template>

<xsl:template match="node()" mode="by-name" />

<xsl:template match="*[text()]" mode="text">
    <xsl:copy />
</xsl:template>

<xsl:template match="*[not(text())]" mode="text">
    <xsl:text>ABSENT</xsl:text>
</xsl:template>

<xsl:template match="/">
    <xsl:apply-templates select="your/current/whatever" />
</xsl:template>

<xsl:template match="*">
    <xsl:for-each select="exslt:node-set($names)/names/n/text()">
        <xsl:apply-templates select="self::*[name() = .]" mode="by-name" />
    </xsl:for-each>
</xsl:template>

将上面的代码放置在一个单独的文件中(变量除外),应将其放置在此处,但将其保留为空。使用xsl:import导入此文件,你现在需要做的唯一事情是重写xsl:variable

在XSLT 2.0和3.0中,有比这更通用和更简单的方法,但是此版本可与XSLT 1.0一起使用。

免责声明:未经测试,可能包含错误,当然可以根据您的需要进行调整;)

更好/通用的方法

是的,您可以这样做。不同的XSLT版本具有不同的抽象级别:

XSLT 1.0

您可以创建一个命名模板(只需为其命名)。如果使用调用命名模板xsl:call-template,则当前上下文项将用作模板内的上下文项。这将解决您的问题,其中包含模板匹配项中的字段名称。

您可以将其放置在单独的文件中,然后使用进行导入,使用xsl:import可以在需要时覆盖它,或者使用xsl:include不允许覆盖,并且在发生命名冲突时会引发错误。

XSLT 2.0

您可以在XSLT 2.0中创建一个可以称为任何其他函数的函数。函数可以包含您上面显示的模板。

在XSLT 2.0中,您也可以使用导入和包含。

XSLT 3.0

您可以执行与以前版本相同的操作,但是现在可以将它们放入(预编译)软件包中,这使得重用,重新分发和调用它们变得更加容易。

此外,XSLT 3.0在覆盖和接受/公开使用过的程序包的组件方面具有大大改进的系统。

所有版本

您可能有一个当前使用的地方xsl:apply-templates如果要防止重复声明匹配项xsl:template,可以通过创建泛型来解决此问题:

<xsl:template match="node()" mode="special">
    <xsl:call-template name="yourNamedTemplate" />
</xsl:template>

然后使用以下方法“调用”该方法:

<xsl:apply-templates select="firstField | secondField | thirdField" mode="special" />

尖端

如果可重用性很重要,那么您的“库样式表”(在XSLT 3.0中会弹出官方术语“库包”),您应该在名称空间中指定模式的名称。实际上,可重用样式表中的任何命名组件(命名模板,模式,函数,累加器,键)都应位于其自己的命名空间中。这样可以防止冲突,如果用户要覆盖冲突,则必须明确地这样做。

您可以创建一个“继承链”。如果A导入B导入了C,则对A中的命名组件,然后是B,然后是C赋予最高优先级。对于冲突的匹配模板,也是如此。(通常)在主体样式表中(通常是这样)是不允许的(因此设置优先级),但是A可以与B或C具有相同的匹配模板。在这种情况下,A越过B越过C越好。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

我可以创建一个Android应用程序作为模板吗?

来自分类Dev

我可以创建一个组件作为属性吗?

来自分类Dev

我可以将模板函数用作另一个模板的参数吗?

来自分类Dev

我可以定义一个返回自己的OCaml函数吗?

来自分类Dev

我可以使一个函数接受通用函数作为参数吗?

来自分类Dev

我可以创建一个函数,该函数是对象中函数的属性吗?

来自分类Dev

我可以自己调用一个nancy模块吗

来自分类Dev

我可以创建一个传递分支名称的git commit模板吗?

来自分类Dev

我可以使用成员函数作为EnumWindows的第一个参数吗

来自分类Dev

我可以使用成员函数作为EnumWindows的第一个参数吗

来自分类Dev

我们可以训练一个模型作为平方函数吗

来自分类Dev

我可以像使用函数一样创建一个重复的类吗

来自分类Dev

我可以创建一个循环来更新SQL数据库吗?

来自分类Dev

我可以创建一个可以解包的类吗?

来自分类Dev

我可以创建一个可以解包的类吗?

来自分类Dev

我可以创建一个过程或函数来删除mysql中的参数表吗?

来自分类Dev

我可以从Postgresql函数内部创建一个临时表吗?

来自分类Dev

我可以创建一个多态的 `mult` 函数,它接受任何数字类型吗?

来自分类Dev

我可以以某种方式创建一个看起来像 .toUpperCase() 的函数吗?

来自分类Dev

我可以创建一个可以采用任何枚举的模板(非类型)参数类吗?C++11

来自分类Dev

我可以将函数调用作为参数传递给另一个函数吗?Python

来自分类Dev

我可以创建一个编译错误来检查一个特性是否具有另一个特性作为超特性吗?

来自分类Dev

我可以创建一个编译错误来检查一个特性是否具有另一个特性作为超特性吗?

来自分类Dev

我可以创建一个列表<WeakReference <T >>吗?

来自分类Dev

RxJS 5:我可以创建一个“ BehaviorObservable”吗?

来自分类Dev

我可以创建一个自毁文件吗?

来自分类Dev

RxJS 5:我可以创建一个“ BehaviorObservable”吗?

来自分类Dev

我可以在Android中创建一个项目并将其用作将来项目的基础模板吗?

来自分类Dev

我们可以从const对象中引用一个setter成员函数作为const吗?

Related 相关文章

  1. 1

    我可以创建一个Android应用程序作为模板吗?

  2. 2

    我可以创建一个组件作为属性吗?

  3. 3

    我可以将模板函数用作另一个模板的参数吗?

  4. 4

    我可以定义一个返回自己的OCaml函数吗?

  5. 5

    我可以使一个函数接受通用函数作为参数吗?

  6. 6

    我可以创建一个函数,该函数是对象中函数的属性吗?

  7. 7

    我可以自己调用一个nancy模块吗

  8. 8

    我可以创建一个传递分支名称的git commit模板吗?

  9. 9

    我可以使用成员函数作为EnumWindows的第一个参数吗

  10. 10

    我可以使用成员函数作为EnumWindows的第一个参数吗

  11. 11

    我们可以训练一个模型作为平方函数吗

  12. 12

    我可以像使用函数一样创建一个重复的类吗

  13. 13

    我可以创建一个循环来更新SQL数据库吗?

  14. 14

    我可以创建一个可以解包的类吗?

  15. 15

    我可以创建一个可以解包的类吗?

  16. 16

    我可以创建一个过程或函数来删除mysql中的参数表吗?

  17. 17

    我可以从Postgresql函数内部创建一个临时表吗?

  18. 18

    我可以创建一个多态的 `mult` 函数,它接受任何数字类型吗?

  19. 19

    我可以以某种方式创建一个看起来像 .toUpperCase() 的函数吗?

  20. 20

    我可以创建一个可以采用任何枚举的模板(非类型)参数类吗?C++11

  21. 21

    我可以将函数调用作为参数传递给另一个函数吗?Python

  22. 22

    我可以创建一个编译错误来检查一个特性是否具有另一个特性作为超特性吗?

  23. 23

    我可以创建一个编译错误来检查一个特性是否具有另一个特性作为超特性吗?

  24. 24

    我可以创建一个列表<WeakReference <T >>吗?

  25. 25

    RxJS 5:我可以创建一个“ BehaviorObservable”吗?

  26. 26

    我可以创建一个自毁文件吗?

  27. 27

    RxJS 5:我可以创建一个“ BehaviorObservable”吗?

  28. 28

    我可以在Android中创建一个项目并将其用作将来项目的基础模板吗?

  29. 29

    我们可以从const对象中引用一个setter成员函数作为const吗?

热门标签

归档