将模板应用于变量/序列中的元素

发布于 2024-09-09 07:50:24 字数 2730 浏览 4 评论 0原文

当我使用“apply-templates”并选择变量序列时,模板是作用于序列中元素的上下文,还是作用于文档中元素的上下文?

在下面的示例中,它似乎要么执行,要么不执行,但我不明白为什么。

<root>
<a/>
<b/>
<c><a/></c>
<a/>
</root>

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="root">
    <!--this variable give me a sequence of "a" elements-->
    <xsl:variable name="someElementA1" select="//a"/>
    <xsl:variable name="someElementA2">
        <xsl:copy-of select="//a"/>
    </xsl:variable>
    <xsl:for-each select="$someElementA1/a">
        <xsl:element name="test">
            <xsl:text>This is scenario 1: </xsl:text>
            <xsl:apply-templates select="."/>
        </xsl:element>
    </xsl:for-each>
    <xsl:for-each select="$someElementA2/a">
        <xsl:element name="test">
            <xsl:text>This is scenario 2: </xsl:text>
            <xsl:apply-templates select="."/>
        </xsl:element>
    </xsl:for-each>
    <xsl:element name="test">
        <xsl:text>This is scenario 3: </xsl:text>
        <xsl:apply-templates select="$someElementA1"/>
    </xsl:element>
    <xsl:element name="test">
        <xsl:text>This is scenario 4: </xsl:text>
        <xsl:apply-templates select="$someElementA2/a"/>
    </xsl:element>
</xsl:template>
<!--these are the templates to apply--> 
<xsl:template match="a[parent::c]">
    <xsl:text>This element has a parent</xsl:text>
</xsl:template>
<xsl:template match="a[parent::root]">
    <xsl:text>This element is in the root element</xsl:text>
</xsl:template>
<xsl:template match="a">
    <xsl:text>This element is in the sequence</xsl:text>
</xsl:template>
</xsl:stylesheet>

输出:

<test>This is scenario 2: This element is in the sequence</test>
<test>This is scenario 2: This element is in the sequence</test>
<test>This is scenario 2: This element is in the sequence</test>
<test>This is scenario 3: This element is in the root elementThis element has a parentThis element is in the root element</test>
<test>This is scenario 4: This element is in the sequenceThis element is in the sequenceThis element is in the sequence</test>

When I use "apply-templates" and select a variable sequence, does the template act upon the context of the element in the sequence, or does it act upon the context of the element in the document?

In the below example, it seems to do either, or none, but I don't understand why.

<root>
<a/>
<b/>
<c><a/></c>
<a/>
</root>

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="root">
    <!--this variable give me a sequence of "a" elements-->
    <xsl:variable name="someElementA1" select="//a"/>
    <xsl:variable name="someElementA2">
        <xsl:copy-of select="//a"/>
    </xsl:variable>
    <xsl:for-each select="$someElementA1/a">
        <xsl:element name="test">
            <xsl:text>This is scenario 1: </xsl:text>
            <xsl:apply-templates select="."/>
        </xsl:element>
    </xsl:for-each>
    <xsl:for-each select="$someElementA2/a">
        <xsl:element name="test">
            <xsl:text>This is scenario 2: </xsl:text>
            <xsl:apply-templates select="."/>
        </xsl:element>
    </xsl:for-each>
    <xsl:element name="test">
        <xsl:text>This is scenario 3: </xsl:text>
        <xsl:apply-templates select="$someElementA1"/>
    </xsl:element>
    <xsl:element name="test">
        <xsl:text>This is scenario 4: </xsl:text>
        <xsl:apply-templates select="$someElementA2/a"/>
    </xsl:element>
</xsl:template>
<!--these are the templates to apply--> 
<xsl:template match="a[parent::c]">
    <xsl:text>This element has a parent</xsl:text>
</xsl:template>
<xsl:template match="a[parent::root]">
    <xsl:text>This element is in the root element</xsl:text>
</xsl:template>
<xsl:template match="a">
    <xsl:text>This element is in the sequence</xsl:text>
</xsl:template>
</xsl:stylesheet>

OUTPUT:

<test>This is scenario 2: This element is in the sequence</test>
<test>This is scenario 2: This element is in the sequence</test>
<test>This is scenario 2: This element is in the sequence</test>
<test>This is scenario 3: This element is in the root elementThis element has a parentThis element is in the root element</test>
<test>This is scenario 4: This element is in the sequenceThis element is in the sequenceThis element is in the sequence</test>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

野却迷人 2024-09-16 07:50:24

您得到的结果是由于以下事实

  1. 节点序列包含它们各自文档中的节点,而不是节点的副本。

  2. 创建由 select 属性中的表达式选择的每个节点的副本。

创建一个新的 XML 片段(临时树),这是变量 $someElementA2 的值

$someElementA1/a

不选择任何节点,因为 $someElementA1 中的所有元素都没有任何子元素名为a

$someElementA2/a

选择作为文档节点 (/) 子级的所有元素 a

The results you get are due to the following facts:

  1. A sequence of nodes contains the nodes as they are in their respective document -- not copies of the nodes.

  2. <xsl:copy-of> creates a copy of each node selected by the expression in the select attribute.

creates a new XML fragment (temporary tree) and this is the value of the variable $someElementA2

$someElementA1/a

does not select any node, because none of the elements in $someElementA1 have any children named a.

$someElementA2/a

selects all elements a that are children of the document node (/).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文