首页 > 解决方案 > 在 XSLT 2.0 中定义变量时使用 xsl:copy-of

问题描述

我(在一个虚构的简化世界中)有一个基本的源 XML 结构:

<?xml version="1.0"?>
<library>
  <book>
    <language>french</language>
    <title>Les Misérables</title>
  </book>
  <book>
    <language>english</language>
    <title>Great Expectations</title>
  </book>
</library>

我使用 xsl:variable 的 select 属性定义了一个变量 myVar1

<xsl:variable name="myVar1" select="library/book[language='french']"/>

我在 xsl:variable 中定义了一个带有 xsl:copy-of 的变量 myVar2

    <xsl:variable name="myVar2">
        <xsl:copy-of select="library/book[language='french']"/>
    </xsl:variable>

我希望 myVar1 和 myVar2 相同,但事实并非如此

    <xsl:value-of select="$myVar1/title"/> <!--result: Les Misérables-->
    <xsl:value-of select="$myVar2/title"/> <!--empty result-->

定义 myVar2 时有什么问题?如何表明我希望它作为结构化的可查询变量(如 myVar1)?如果我有几个条件语句来定义变量,则使用 select 并不方便。

这是完整的 XSLT 文件

<?xml version='1.0'?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/">

    <xsl:variable name="myVar1" select="library/book[language='french']"/>

    <xsl:variable name="myVar2">
      <xsl:copy-of select="library/book[language='french']"/>
    </xsl:variable>

    <xsl:value-of select="$myVar1/title"/>
    <xsl:value-of select="$myVar2/title"/>

  </xsl:template>
</xsl:stylesheet>

标签: xmlvariablesxslt

解决方案


规则在https://www.w3.org/TR/xslt-30/#variable-values

快速总结:如果没有select属性和没有as属性,那么变量的值是一个新的文档节点,其中包含作为子元素复制的元素。正是这个额外的级别阻止了您的路径表达式的工作。select="library/book"变量的值是一个book元素,序列构造函数的值是一个文档节点,该节点有一个元素book作为其子节点。


推荐阅读