我不是XSLT大师,也无法在网上找到类似的例子。我想将多个文件中的应用程序列表组合成一个可用于搜索的var。
基本上当我用新的替换原始变量decleration时,XSLT不喜欢它。我确实将变量内容输出到文件中,并且它们在XML元素的格式化方面是相同的,因此它必须在某处链接到变量的某些元数据失败。
所有文件中的XML元素格式
<include-application name="appname" type="blah"/>
原始变量
<xsl:variable name="applications" select="board/packaging/*/include-application"/>
新变量定义
<xsl:variable name="applications">
<xsl:copy-of select="board/packaging/*/include-application"/>
<xsl:for-each select="board/packaging/applications/include">
<xsl:variable name="appset" as="xs:string" select="@name"/>
<xsl:variable name="includefile" as="xs:string" select="concat('../share/appsets/', $appset, '.xml')"/>
<xsl:copy-of select="document($includefile)/applications/include-application"/>
</xsl:for-each>
</xsl:variable>
然后,当我尝试访问元素以选择某些东西时,它会失败并带有新的变量定义(第39行是下面块中的第一个)。
<xsl:variable name="type" select="$applications[@name = $appname]/@type"/>
<xsl:variable name="appid" select="$app-names/application-package-name[@name = $appname]/appid[@type = $type]/@value"/>
XPath错误:类型无效 运行时错误:文件xslt / blah.xslt第39行元素变量 无法评估变量'type'的表达式。
由于
大卫
答案 0 :(得分:0)
问题应该是变量包含XML片段而不是节点集(例如参见this) - 不同的XSLT处理器具有不同的扩展函数来进行转换 - 例如使用Microsoft处理器你会这样做:
<xsl:variable name="type" select="msxsl:node-set($applications)[@name = $appname]/@type"/>
其他处理器具有不同的功能(或不同命名空间中的相同功能)
答案 1 :(得分:0)
由于您正在使用XSLT 2.0,正如您使用as=
所证明的那样,您需要声明变量的内存组织,以便稍后对其进行操作。我认为您只需将变量的第一行更改为:
<xsl:variable name="applications" as="element(include-application)*">
...
这将告诉处理器不要构建树,而是建立一个节点集。
我的XSLT书籍的第223页提供了有用的信息和图表,可以在http://www.CraneSoftwrights.com/training/#ptux以“试用和购买”的形式免费下载...如果您决定不支付该书费用,请删除您免费下载的副本。
答案 2 :(得分:0)
结合使用上述答案并深入研究,我使用exslt扩展转换为节点集,现在可以完美运行。
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:exslt="http://exslt.org/common">
...
<xsl:variable name="applications" as="element(include-application)*">
...
<xsl:variable name="type" select="exslt:node-set($applications)/include-application[@name = $appname]/@type"/>