代码之家  ›  专栏  ›  技术社区  ›  Martin Smith

用于属性的XSLT内置模板规则

  •  7
  • Martin Smith  · 技术社区  · 15 年前

    我敢肯定这是一个非常基本的问题,但不管怎么说,这就是问题了!我已经阅读过,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中应用转换得到以下输出。有人能解释一下为什么我在输出中看不到“测试”吗?

    阿拉文德·阿迪加

    白虎

    二千零八

    3 回复  |  直到 15 年前
        1
  •  6
  •   Vincent Marchetti    15 年前

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

    <xsl:template match="*">
        <xsl:apply-templates select="@*"/>
        <xsl:apply-templates/>
    </xsl:template>
    
        2
  •  6
  •   Krab    15 年前

    要从评论中解决此问题:

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

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

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

    处理文档时,第二个模板与根匹配并应用模板。应用模板的默认设置是选择所有子节点(令人困惑的是,属性不是子节点)。您从不选择任何要处理的属性,因为 apply-templates 以默认形式显示。

    因此,如果您在某个地方选择了任何属性(如Vincent Marchetti所做的),它将被第一个提到的默认模板处理。

        3
  •  2
  •   ZXX    15 年前

    主要规则是-属性根本没有标识-它们只能作为附加到节点上的侧向位进行访问 . 最好将它们视为不存在的,直到您首先拥有一个节点为止。您也可以将它们视为XPath和XSLT世界中的完全二级公民。每次在选择条件中使用它们,就像在SQL中从联接切换到光标,每次使用“for”而不是“apply”时,都会发生同样的情况。

    另一种说法是-唯一真正有效的“索引”是文档中包含所有xpaths的索引(.net实际上构建了xpaths的hashtable=>常量时间匹配)。之所以“应用”具有特权,是因为它保证了纯粹的功能处理—您可以在单独的线程上运行apply匹配的所有内容,而不需要同步和内存共享—您只需确认它们的结果。

    第三种方法是看它,这是一个延伸,假设您的标记是SQL表,并且您只有代理pk-s和fk-s——除了“从T1全部选择,从t2全部与之相关”,没有其他选择。对于任何一个像样的SQL引擎来说,这就像是一个零成本的工作——它只是逐条读取一个好的索引项,因为它的结构对于您的查询来说是1-1。其他的东西都要贵得多。

    一旦您选择了标签,并且模板匹配并运行,那么只获取属性值就很便宜了——只要您只是转换/呈现它们。xpath末尾的attrib测试也相当便宜,因为最终的标签/节点是被选中的,现在它只是上面的一个小过滤器。

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