2010-05-14 67 views
7

我相信这是一个非常基本的问题,但无论如何,这里仍然存在!我已阅读,内置的模板规则文本和XSLT属性节点是XSLT内置模板属性规则

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

但是源文档

<?xml version="1.0"?> 
<booker> 
<award> 
    <author blah="test">Aravind Adiga</author> 
    <title>The White Tiger</title> 
    <year>2008</year> 
</award> 
</booker> 

和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> 

我得到以下输出在Visual Studio中应用转换。有人能解释为什么我在输出中看不到“测试”吗?

阿拉文·阿迪加

白虎

回答

6

由于对要素内置的规则并不模板应用到元素自身的属性,只有它的子元素。如果你想以同样的方式来遍历属性您遍历子元素(这可能是一个人工任务),你需要定义自己的默认:

<xsl:template match="*"> 
    <xsl:apply-templates select="@*"/> 
    <xsl:apply-templates/> 
</xsl:template> 
+1

我同意,只是为了增加完整性 - 默认的''选择所有的子节点,不仅仅是元素(否则没有什么会被代码从问题中输出)。 – Krab 2010-05-14 16:06:00

+0

谢谢,我不需要真的这样做,我只是想了解规则。所以基本上,内建规则的“@ *”部分将永远不会被调用,除非它被明确调用? – 2010-05-14 16:10:01

6

要评论解决这个问题:

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

在这种情况下,有利息我们两个默认的规则:

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

<xsl:template match="/|*"> 
    <xsl:apply-templates/> 
</xsl:template> 

当文档被处理时,第二个模板根匹配并应用模板。 apply-templates的默认值是选择所有的子节点(属性,容易混淆,不是子节点)。您从不选择任何要处理的属性,因为唯一的apply-templates以其默认形式出现。

所以如果你选择了某个地方的任何属性(如Vincent Marchetti所做的),它将由第一个提到的默认模板进行处理。

+0

+1我看到了!感谢这一切现在是有道理的。 – 2010-05-14 16:20:07

2

主要规则是 - 属性根本没有标识 - 它们只能作为连接到节点的横向位来访问。在您首先创建节点之前,将它们视为不存在是很好的。您也可以将它们视为XPath和XSLT世界中的完全二等公民。每次在选择条件中使用它们就像在SQL中从一个连接切换到一个游标,并且每次使用“for”而不是“apply”时,都会发生同样的情况。

另一种方式来说 - 你唯一真正有效的“索引”是在文档中包含所有XPath的。(.Net实际上构建了XPaths的Hashtable =>常量时间匹配)。 “应用”是有特权的原因是它保证了纯粹的功能处理 - 你可以运行匹配的所有东西,通过适用于单独的线程而不需要同步,也不需要共享内存 - 你只需要连接它们的结果。

第三种方式来看看它,这是一个延伸,想象你的标签是SQL表,并且只有代理PK-s和FK-s - 除了“全部来自T1和全部与T2相关“。对于任何体面的SQL引擎来说,它就像是一个零成本的工作 - 它只是逐条地读取一个好的索引,因为它的结构在查询时为1-1。其他一切花费更多。

一旦你选择了标签并且模板匹配并运行,那么只要获取属性的值就很便宜 - 只要你转换/渲染它们即可。 XPath结束时的属性测试也相当便宜 - 同样,因为最终的标签/节点已被选中,现在它只是一个小小的过滤器。

所以,XSLT引擎和XPath选择一般都有很好的理由完全忽略attributes - perf。