XSLT属性的内置模板规则

Mar*_*ith 7 xslt

我确信这是一个非常基本的问题,但无论如何都要进行!我已经读过XSLT中文本和属性节点的内置模板规则

<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

但是对于源文档

<?xml version="1.0"?>
<booker>
 <award>
  <author blah="test">Aravind Adiga</author>
  <title>The White Tiger</title>
  <year>2008</year>
 </award>
</booker>
Run Code Online (Sandbox Code Playgroud)

和XSLT

<?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"/>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)

我得到以下输出应用Visual Studio中的转换.有人可以解释为什么我在输出中没有看到"测试"吗?

Aravind Adiga

白虎

2008年

Vin*_*tti 6

因为元素的内置规则不会将模板应用于元素自己的属性,而只应用于元素的子元素.如果要以遍历子元素的相同方式遍历属性(这可能是一个人工任务),您需要定义自己的默认值:

<xsl:template match="*">
    <xsl:apply-templates select="@*"/>
    <xsl:apply-templates/>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)


Kra*_*rab 6

从评论中解决这个问题:

谢谢,我不需要真正去做,我只是想了解规则.所以基本上内置规则的@*部分永远不会被调用,除非它被显式调用?

在这种情况下,有两个我们感兴趣的默认规则:

<xsl:template match="text()|@*">
  <xsl:value-of select="."/>
</xsl:template>

<xsl:template match="/|*">
  <xsl:apply-templates/>
</xsl:template>
Run Code Online (Sandbox Code Playgroud)

处理文档时,第二个模板与根和apply-templates匹配.apply-templates的默认设置是选择所有子节点(属性,容易混淆,不是子节点).您永远不会选择要处理的任何属性,因为它只apply-templates显示在其默认表单中.

因此,如果您选择任何属性(如Vincent Marchetti所做的那样),它将由第一个提到的默认模板处理.