我不明白 apply-templates 在 XSLT 中如何工作。
现在我有这个 XML 文档:
<?xml version="1.0" encoding="UTF-8"?>
<people>
<person>
<name>John Doe</name>
<age>30</age>
<occupation>Software Engineer</occupation>
</person>
<person>
<name>Jane Smith</name>
<age>28</age>
<occupation>Graphic Designer</occupation>
</person>
<person>
<name>Sam Brown</name>
<age>35</age>
<occupation>Data Analyst</occupation>
</person>
</people>
这个 XSLT:
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
<!-- Output -->
<xsl:output method="html" />
<!-- Default template -->
<xsl:template match="/">
<html>
<body>
<xsl:apply-templates />
</body>
</html>
</xsl:template>
<!-- Adding ages -->
<xsl:template match="person">
<p>
<xsl:value-of select="./name/text()" />
</p>
</xsl:template>
<!-- Adding names -->
<xsl:template match="age">
<p>
<xsl:value-of select="./text()" />
</p>
</xsl:template>
</xsl:stylesheet>
当我运行它时,我得到的结果是这样的:
<html>
<body>
<p>John Doe</p>
<p>Jane Smith</p>
<p>Sam nkmk</p>
</body>
</html>
这是出乎意料的,因为我想要人们的姓名和年龄,因为我定义了两个模板。
在对这个问题的一个答案中,下面说XSLT默认模板规则的定义方式是,默认情况下,它们将匹配文档的顶部节点,然后以递归方式处理每个子节点,一直到底部,这很公平,所以从技术上讲,人们会期望先处理person节点,然后是它的子节点,因为有一个年龄模板,所以应该将年龄添加到html中,但事实并非如此。 (此外,根据这个问题的第一个答案,它甚至应该打印姓名和职业,因为我没有定义与文本匹配的模板,例如<xsl:template match="text()"> )。
鉴于我是 XSLT 新手,这一切对我来说非常令人困惑。
你能向我解释一下这里发生了什么吗?
您的引文遗漏了一个重要部分,即“默认”。
您的模板匹配
person
会覆盖默认的内置模板- 并且它不会将模板应用于 的age
(或任何其他) 子级person
。因此,模板匹配age
永远不会被实例化,否则将处理 的其他子级的内置模板也不会被实例化person
。