我是xml的新手,我试图理解xslt
的一个例子xml
<?xml version="1.0" encoding="utf-8"?>
<ts>
<t id="t1">T1</t>
<t id="t2" ref="t1">T2</t>
<t id="t3" ref="t2">T3</t>
</ts>
1)第一个xsl
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="key" match="t" use="@id"/>
<xsl:template match="/|*|text()">
<xsl:copy>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/t[@ref]">
<xsl:copy-of select="key('key',@ref)"/>
</xsl:template>
</xsl:stylesheet>
2)第二个xsl
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="key" match="t" use="@id"/>
<xsl:template match="/|*|text()">
<xsl:copy>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="t[@ref]">
<xsl:apply-templates select="key('key',@ref)"/>
</xsl:template>
</xsl:stylesheet>
结果如下: 1)
<?xml version="1.0"?>
<ts>
<t>T1</t>
<t id="t1">T1</t>
<t id="t2" ref="t1">T2</t>
</ts>
2)
<?xml version="1.0"?>
<ts>
<t>T1</t>
<t>T1</t>
<t>T1</t>
</ts>
任何人都可以告诉我它是如何工作的,特别是第二个xsl如何给出三个T1的结果。 非常感谢你的帮助:)
答案 0 :(得分:0)
关于您的第一个样式表:
第二个模板:
<xsl:template match="/t[@ref]">
<xsl:copy-of select="key('key',@ref)"/>
</xsl:template>
与给定XML文档中的任何内容都不匹配,因为没有t
元素是/
根节点的子元素。所以你的样式表所做的就是按照第一个模板的原样复制给定的XML文档。
关于您的第二个样式表:
为了更好地理解这里发生的事情,我建议你将第二个模板更改为:
<xsl:template match="t[@ref]">
<instance>
<xsl:copy-of select="key('key',@ref)"/>
</instance>
</xsl:template>
结果将是:
<ts>
<t>T1</t>
<instance>
<t id="t1">T1</t>
</instance>
<instance>
<t id="t2" ref="t1">T2</t>
</instance>
</ts>
这告诉我们什么?
您可以看到第二个模板已实例化两次(这是预期的,因为恰好有两个t
元素具有@ref
属性。
请记下密钥调用的节点。
现在,如果再次将模板更改为:
<xsl:template match="t[@ref]">
<instance>
<xsl:apply-templates select="key('key',@ref)"/>
</instance>
</xsl:template>
结果将是:
<ts>
<t>T1</t>
<instance>
<t>T1</t>
</instance>
<instance>
<instance>
<t>T1</t>
</instance>
</instance>
</ts>
如您所见,模板的第二个实例导致了同一模板的另一个第三个实例化。这是因为第二个实例将模板应用于:
<t id="t2" ref="t1">T2</t>
节点,其本身具有@ref
属性,因此由相同的模板匹配。但是,这次键调用:
<t id="t1">T1</t>
节点,不具有@ref
属性,因此将被第一个模板复制。