在我的场景中,什么是最好的XSLT XPath性能?

时间:2015-04-29 09:06:11

标签: xml performance xslt xpath xslt-1.0

我对XSLT XPath性能有疑问。如果我们查看以下示例。

以下哪个选项具有最佳效果:

<xsl:for-each select="//cd">

<xsl:for-each select="//catalog/cd">

XML数据:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <catalog>
        <cd>
            <title>Empire Burlesque</title>
            <artist>Bob Dylan</artist>
        </cd>
        <cd>
            <title>Hide your heart</title>
            <artist>Bonnie Tyler</artist>
        </cd>
    </catalog>
    <catalog>
        <cd>
            <title>Greatest Hits</title>
            <artist>Dolly Parton</artist>
        <cd>
            <title>Still got the blues</title>
            <artist>Gary Moore</artist>
        </cd>
    </catalog>
</root>

XSLT样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
  <html>
  <body>
    <h2>My CD Collection</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>Title</th>
        <th>Artist</th>
      </tr>
      <xsl:for-each select="//cd">
      <tr>
        <td><xsl:value-of select="title" /></td>
        <td><xsl:value-of select="artist" /></td>
      </tr>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>
</xsl:stylesheet>

哪个表现最佳?

(我已经做了这个更小的更简单的例子,在我的实际案例中,我有更复杂的数据结构)

3 个答案:

答案 0 :(得分:1)

这个问题唯一可能的答案是“这取决于处理器”。作为一项规则,您应该避免使用//不一定,但聪明的处理器可能能够优化简单的//something绝对路径(例如,使用哈希表按名称查找节点)比完全指定的/root/catalog/cd

您必须根据特定数据分析特定处理器。

答案 1 :(得分:1)

测量并查看。在建立测量框架之前,您甚至不应该开始研究提高性能的方法。如果你有一个测量框架,你不需要在这里提出问题,如果你没有问题,你就无法评估答案。

答案 2 :(得分:0)

首先,您的输入文档格式不正确;其中一个cd元素未关闭,并且没有单个最外层元素包含其他所有元素。假设有以下输入:

XML输入

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <catalog>
        <cd>
            <title>Empire Burlesque</title>
            <artist>Bob Dylan</artist>
        </cd>
        <cd>
            <title>Hide your heart</title>
            <artist>Bonnie Tyler</artist>
        </cd>
    </catalog>
    <catalog>
        <cd>
            <title>Greatest Hits</title>
            <artist>Dolly Parton</artist>
        </cd>
        <cd>
            <title>Still got the blues</title>
            <artist>Gary Moore</artist>
        </cd>
    </catalog>
</root>

现在,关于您的问题:您既不应使用<xsl:for-each select="//cd">也不应使用<xsl:for-each select="//catalog/cd">。实际上,你根本不应该使用xsl:for-each,没有理由在这里使用它。您最好学习如何编写单独的模板来完成工作,例如下面的样式表。

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="html" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/root">
      <html>
      <body>
        <h2>My CD Collection</h2>
        <table border="1">
          <tr bgcolor="#9acd32">
            <th>Title</th>
            <th>Artist</th>
          </tr>
          <xsl:apply-templates/>
        </table>
      </body>
      </html>
    </xsl:template>

    <xsl:template match="cd">
        <tr>
            <xsl:apply-templates/>
        </tr>
    </xsl:template>

    <xsl:template match="title|artist">
        <td>
            <xsl:value-of select="."/>
        </td>
    </xsl:template>

</xsl:stylesheet>

虽然输出完全相同并且可以使用xsl:for-each,但for-each是一个严重过度使用的构造,特别是初学者 - 在模板更优雅的地方。

  

哪个表现最好?

这个问题与XSLT无关,它与嵌入在XSLT中的XPath表达式有关:

<xsl:for-each select="//cd">
^^^^^^^^^^^^^^^^^^^^^^    ^^      XSLT
                      ^^^^        XPath

通常,XPath表达式应该避免使用//descendant-or-self::)轴。你应该总是不愿意使用//,只有在输入文档的结构真的不可预测或者你想要定位的元素被任意嵌套时才使用它。