结果树片段到节点集:所有 xsl 引擎的通用方法 [英] result tree fragment to node-set: generic approach for all xsl engines

查看:17
本文介绍了结果树片段到节点集:所有 xsl 引擎的通用方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

回答另一个线程(见 stackoverflow:生成 css 配色方案) 我遇到了下面的问题,不同的 xsl 引擎似乎需要不同的方法将结果树片段转换为节点集.

Answering another thread (see stackoverflow: generate css color schemes) I bumped into the issue below, where different xsl engines seem to need different approaches in transforming result tree fragments into node-sets.

简化问题(但请参阅上面的链接了解其背后的完整故事),我希望有一个包含颜色值列表的内联树.由于必须在 Xpath 表达式中使用它,因此我必须从它专门为 MSXML x.x xsl 引擎创建一个节点集(XML Spy 内置在解释包含构造为 rtf 的变量的 Xpath 表达式时没有那么麻烦).
另一个线程 stackoverflow:automating-exsltnode-set 帮助了我.生成的节点集用于从输入 XML 创建新变量 rtf.
同样,当在 Xpath 表达式中使用新变量时,MSXML 会抱怨,因此我使用节点集函数从它创建节点集.
到目前为止一切顺利,MSXML x.x 不再出错.
但是当我在内置的 XML Spy 或 Saxon 9he 中运行相同的程序时,我得到另一个错误:似乎 node-set 函数是未知的:

Simplifying the issue (but see link above for the full story behind this), I wish to have an inline tree containing a list of color values. As this has to be used in Xpath expressions, I had to create a node-set from it specifically for MSXML x.x xsl engine (XML Spy built-in had less trouble interpreting Xpath expressions contaning variables constructed as rtf's).
Yet another thread stackoverflow: automating-exsltnode-set helped me there. The resulting node-set is used in creating a new variable rtf from the input XML.
Again, MSXML complains when the new variable is used in Xpath expressions, so I used the node-set function to create a node-set from it.
So far so good, and MSXML x.x does not error any more.
But when I run the same in XML Spy built-in or Saxon 9he, I get another error: it seems that the node-set function is unknown:

Cannot find a matching 1-argument function named {urn:schemas-microsoft-com:xslt}node-set() in variable colorList

请注意,在此特定示例中不需要这种两步法,但正如我所说,我简化了事情;我只想知道如何编写一个适用于所有 xsl 引擎的 XSLT 1.0 转换.

Note that this two-step approach is not needed in this particular example, but as I said I simplified things; I just wish to know how to write an XSLT 1.0 transformation that will work in all xsl engines.

我使用的 XSLT:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet
    version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:std="http://whatever"
    xmlns:exslt="urn:schemas-microsoft-com:xslt"
    exclude-result-prefixes="std exslt">

    <xsl:output method="xml" indent="yes"/>

    <std:colors>
        <color>#0000FF</color>
        <color>#FF0000</color>
    </std:colors>

    <xsl:variable name="colors" select="document('')/*/std:colors"/>

    <xsl:variable name="std:colorList">
        <xsl:for-each select="//testid">
            <xsl:variable name="pos" select="position() mod 2"/>
            <xsl:element name="color">
                <xsl:attribute name="testid"><xsl:value-of select="."/></xsl:attribute>
                <xsl:value-of select="$colors/color[$pos + 1]"/>
            </xsl:element>
        </xsl:for-each>
    </xsl:variable>

    <xsl:variable name="colorList" select="exslt:node-set($std:colorList)"/>

    <xsl:template match="/">
        <output>
            <xsl:copy-of select="$colorList/color"/>
        </output>
   </xsl:template>

</xsl:stylesheet>

输入文件:

<?xml version="1.0" standalone="yes"?>
<NewDataSet>
  <defects>
    <testid>111</testid>
  </defects>
  <defects>
    <testid>999</testid>
  </defects>
</NewDataSet>

结果为 MSXML 3.0/4.0/6.0:

Result in MSXML 3.0/4.0/6.0:

<?xml version="1.0" encoding="UTF-16"?>
<output>
<color testid="111">#FF0000</color>
<color testid="999">#0000FF</color>
</output>

在 Saxon9he 中的结果:

Result in Saxon9he:

Cannot find a matching 1-argument function named {urn:schemas-microsoft-com:xslt}node-set()
in variable colorList

导致 XML Spy 内置 xsl 引擎:

result in XML Spy built-in xsl engine:

Error in XPath expression
Unknown function - Name and number of arguments do not match any function signature in the static context - 'urn:schemas-microsoft-com:xslt:node-set'

推荐答案

对于 MSXML 以外的处理器,请使用 exslt:node-set() 函数.(http://www.exslt.org/).(将 exslt 前缀绑定到该函数的 Microsoft 版本有点奇怪 - 这让我困惑了一段时间!)

For processors other than MSXML, use the exslt:node-set() function. (http://www.exslt.org/). (It's a little odd to bind the exslt prefix to the Microsoft version of the function - that had me confused for a while!)

您可以使用 function-available() 测试哪些函数可用:

You can test which functions are available using function-available():

<xsl:choose>
  <xsl:when test="function-available('exslt:node-set')"...
  <xsl:when test="function-available('msxsl:node-set')"...

对于 Saxon-HE 和其他 XSLT 2.0 处理器,您不需要任何这些功能,所以使用

For Saxon-HE and other XSLT 2.0 processors you don't need any of these functions, so use

<xsl:when test="xsl:version='2.0'">

这篇关于结果树片段到节点集:所有 xsl 引擎的通用方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆