将模板应用于变量/序列中的元素
当我使用“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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您得到的结果是由于以下事实:
节点序列包含它们各自文档中的节点,而不是节点的副本。
创建由select
属性中的表达式选择的每个节点的副本。创建一个新的 XML 片段(临时树),这是变量
$someElementA2
的值不选择任何节点,因为
$someElementA1
中的所有元素都没有任何子元素名为a
。选择作为文档节点 (
/
) 子级的所有元素a
。The results you get are due to the following facts:
A sequence of nodes contains the nodes as they are in their respective document -- not copies of the nodes.
<xsl:copy-of>
creates a copy of each node selected by the expression in theselect
attribute.creates a new XML fragment (temporary tree) and this is the value of the variable
$someElementA2
does not select any node, because none of the elements in
$someElementA1
have any children nameda
.selects all elements
a
that are children of the document node (/
).