构建而不是选择 XSL 节点集变量 [英] Constructing, not selecting, XSL node set variable

查看:27
本文介绍了构建而不是选择 XSL 节点集变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望使用包含的 for-each 循环构造一个 XSL 节点集变量.重要的是,构建的节点集是原始(选定的)节点集,而不是副本.

这是我的问题的简化版本(当然可以通过选择解决,但这不是问题的重点).我使用了 <name>node 来测试构造的节点集变量实际上是在原始树中而不是副本中.

XSL 版本 1.0,处理器为 msxsl.

非工作 XSL:

XML 输入:

<姓名>X</姓名><entry>1</entry><entry>2</entry></root>

想要的输出:

X1X2

实际输出:

12

当然,(或 a)问题是副本,但我无法解决这个问题.

解决方案

在 XSLT 1.0 中没有解决方法" - 这正是它应该如何工作的.当您有一个用内容而不是用 select 声明的变量时,该内容是由新创建的节点组成的结果树片段(即使这些节点是原始树中节点的副本).如果要引用附加到原始树的原始节点,则必须使用 select 声明变量.更好的问题是详细说明实际问题,并询问如何编写合适的 select 表达式来查找所需的节点,而无需使用 for-each - 大多数用途xsl:ifxsl:choose 可以替换为适当构造的谓词,可能涉及对 xsl:key 等的明智使用.><小时>

在 XSLT 2.0 中,它更加灵活.节点集和结果树片段之间没有区别,并且 xsl:variable 的内容被视为通用的序列构造函数",如果您构造或复制它们,它可以为您提供新节点:

<xsl:copy-of select="//entry"/></xsl:变量>

或原始节点,如果您使用 xsl:sequence:

<xsl:sequence select="//entry"/></xsl:变量>

I wish to construct an XSL node set variable using a contained for-each loop. It is important that the constructed node set is the original (a selected) node set, not a copy.

Here is a much simplified version of my problem (which could of course be solved with a select, but that's not the point of the question). I've used the <name> node to test that the constructed node set variable is in fact in the original tree and not a copy.

XSL version 1.0, processor is msxsl.

Non-working XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="iso-8859-1" omit-xml-declaration="yes" />

<xsl:template match="/">

    <xsl:variable name="entries">
        <xsl:for-each select="//entry">
            <xsl:copy-of select="."/>
        </xsl:for-each>
    </xsl:variable>

    <xsl:variable name="entryNodes" select="msxsl:node-set($entries)"/>

    <xsl:for-each select="$entryNodes">
        <xsl:value-of select="/root/name"/>
        <xsl:value-of select="."/>
    </xsl:for-each>

</xsl:template>

</xsl:stylesheet>

XML input:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <name>X</name>
    <entry>1</entry>
    <entry>2</entry>
</root>

Wanted output:

X1X2

Actual output:

12

Of course the (or a) problem is the copy-of, but I can't work out a way around this.

解决方案

There isn't a "way around it" in XSLT 1.0 - it's exactly how this is supposed to work. When you have a variable that is declared with content rather than with a select then that content is a result tree fragment consisting of newly-created nodes (even if those nodes are a copy of nodes from the original tree). If you want to refer to the original nodes attached to the original tree then you must declare the variable using select. A better question would be to detail the actual problem and ask how you could write a suitable select expression to find the nodes you want without needing to use for-each - most uses of xsl:if or xsl:choose can be replaced with suitably constructed predicates, maybe involving judicious use of xsl:key, etc.


In XSLT 2.0 it's much more flexible. There's no distinction between node sets and result tree fragments, and the content of an xsl:variable is treated as a generic "sequence constructor" which can give you new nodes if you construct or copy them:

<xsl:variable name="example" as="node()*">
  <xsl:copy-of select="//entry" />
</xsl:variable>

or the original nodes if you use xsl:sequence:

<xsl:variable name="example" as="node()*">
  <xsl:sequence select="//entry" />
</xsl:variable>

这篇关于构建而不是选择 XSL 节点集变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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