Variables XSLT:变量和;“空的”;标签

Variables XSLT:变量和;“空的”;标签,variables,xslt,Variables,Xslt,我有一个XML数据文件,其中包含任意多个逗号分隔值的字符串。我希望这些值在web浏览器中显示为每行一个值的列表。因此,我编写了一个XSLT模板,它接受这个字符串,显示第一个值,后跟一个换行标记(),适当的名称间隔,以及字符串剩余部分的资源。实际上,逗号正被HTML标记所取代 现在,当我将调用该模板的结果存储在xsl:variable中,并通过xsl:value of显示该结果时,HTML标记消失了:显示的是字符串减去逗号 当我用xsl:call模板代替xsl:value of直接显示结果时,一切

我有一个XML数据文件,其中包含任意多个逗号分隔值的字符串。我希望这些值在web浏览器中显示为每行一个值的列表。因此,我编写了一个XSLT模板,它接受这个字符串,显示第一个值,后跟一个换行标记(

),适当的名称间隔,以及字符串剩余部分的资源。实际上,逗号正被HTML

标记所取代

现在,当我将调用该模板的结果存储在
xsl:variable
中,并通过
xsl:value of
显示该结果时,HTML标记消失了:显示的是字符串减去逗号

当我用
xsl:call模板
代替
xsl:value of
直接显示结果时,一切正常,值显示在列表中

那么,发生了什么事?

这种行为是一种实现工件,还是标准XSLT?

您似乎触及了以下界限:

当使用XML片段初始化变量或参数时,该变量或参数是 “结果树片段”数据类型。这是XSLT1.0特定的数据类型[与节点集类似,但略有不同]。 结果树片段相当于只包含根节点的节点集。
不能对结果树片段应用“/”、“//”或谓词之类的运算符。它们仅适用于节点集数据类型。
[…]
a) 在XSLT1.0中
解决方法是将结果树片段转换为节点集。我不知道有任何特定于oracle的xpath扩展函数可以为您做到这一点。
您可以使用EXSLT来实现这一点。
b) 使用XSLT2.0
您可以在XSLT2.0中编写转换代码。XSLT 2.0不推荐ResultTreeFragments,即,如果您正在对XSLT 2.0转换进行建模,并且您创建了一个包含树片段的变量或参数,则它隐式地是一个节点序列

因此,如果不使用大于1的XSLT版本,您就太倒霉了。所以最好使用XSLT-2.0或3.0来解决这个问题

这种行为是实现工件还是标准XSLT

它是XSLT-1.0的标准,但不适用于XSLT-2.0+。

如果要输出节点(如
br
元素),
xsl:value of
将使用选定的字符串值创建简单的文本节点

这里有一个示例显示了
xsl:value of
xsl:copy of
之间的差异,您会注意到,造成差异的不是将变量与新创建的
br
元素一起使用,而是使用
xsl:value of
创建了
文本()
节点,具有所选内容的字符串转换:

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

  <xsl:output method="html" indent="yes" version="5" doctype-system="about:legacy-doctype"/>

  <xsl:variable name="var">Phrase 1.<br/>Phrase 2.<br/>Phrase 3.</xsl:variable>

  <xsl:template match="/">
    <html>
      <head>
        <title>.NET XSLT Fiddle Example</title>
      </head>
      <body>
          <section>
              <h1>Example 1: value-of</h1>
              <xsl:value-of select="$var"/>
          </section>
          <section>
              <h1>Example 2: copy-of</h1>
              <xsl:copy-of select="$var"/>
          </section>
          <xsl:apply-templates select="//p"/>
          <xsl:apply-templates select="//p" mode="copy-of"/>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="p">
      <section>
          <h1>Example 1: value-of</h1>
          <xsl:value-of select="."/>
      </section>
  </xsl:template>

  <xsl:template match="p" mode="copy-of">
      <section>
          <h1>Example 1: copy-of</h1>
          <xsl:copy-of select="."/>
      </section>
  </xsl:template>

</xsl:stylesheet>

好吧,可以肯定的是,我的问题已经解决了——不使用中间变量(它是XSLT-1.0)。因此,显然,使用变量存储模板调用的结果比仅存储结果要复杂得多,在我的例子中是删除空标记。@dehulst,您可以在所有版本的XSLT中将带有节点的变量复制到输出中,但您需要使用
来实现这一点,
将使用变量选择的字符串值创建一个文本节点,这意味着像
br
元素这样的任何节点都将被剥离。这就是
xsl:value of
的工作原理,即使选择了输入元素,也会得到一个带有字符串值的文本节点,而不是输出中的节点。看啊,这是有道理的
xsl:value of
不仅生成文本,而且在树中创建一个文本节点,由于文本节点不能包含子节点,因此存在的任何子节点(如从另一棵树插入的节点my tags)都会被剥离。谢谢,马丁。
Example 1: value-of
Phrase 1.Phrase 2.Phrase 3.
Example 2: copy-of
Phrase 1.
Phrase 2.
Phrase 3.
Example 1: value-of
Line 1.Line 2.Line 3.
Example 1: copy-of
Line 1.
Line 2.
Line 3.