xslt性能问题与大if条件

时间:2015-10-29 10:46:50

标签: xml xslt if-statement

在我的xslt中我有像

这样的代码
 <xsl:param name="acceptType"/>
 <xsl:template match="element-1|element-2............|element-n>
   <xsl:if test=".!=''">           
         <xsl:if test="not(contains($acceptType, 'xml'))">
            <xsl:element name="{local-name()}">
               <xsl:value-of select="$pARRAY"/>
            </xsl:element>
         </xsl:if>
      </xsl:if>
   </xsl:template>

这里我有近1000个元素。因为这个条件检查我们遇到了性能问题。有没有其他方法可以做到这一点?。我想放一个全局布尔变量并想检查那个变量。是它提高绩效的正确方法。

提前致谢..

2 个答案:

答案 0 :(得分:1)

绝对衡量而不是猜测性能。

但是,在此期间,您可以使用一些替代方法来消除单个匹配模板中的1000个元素:

  1. 更改为match="*",然后为其添加单独的match="element-i"模板 每个其他i .. N元素不在原始1000中。这应该 如果N远小于1000,请参阅帮助,或参见#2:
  2. 更改为match="*[ 某些条件 ],其中some condition 涵盖了element-1element-2,......
    • string(number(substring-after(local-name(), '-')) = 'Nan'会 测试匹配的元素名称是否以- 数字结尾。
    • child将测试一个常见的子元素。
    • @attr > 0会测试肯定的@attr
  3. 对于您的特定XSLT处理器,是否应该根据经验确定其中任何一个是否更快。但是,如果适用,这些替代方案至少可以具有代码维护(如果不是性能)。

    更新Abel's comment怀疑match="x|y|z"性能下降是否有意义。请尝试使用test=". != ''"替换test="node()"测试更多关注他的内容:

     <xsl:param name="acceptType"/>
     <xsl:template match="element-1|element-2............|element-n>
       <xsl:if test="node()">           
           <xsl:if test="not(contains($acceptType, 'xml'))">
              <xsl:element name="{local-name()}">
                 <xsl:value-of select="$pARRAY"/>
              </xsl:element>
           </xsl:if>
         </xsl:if>
      </xsl:template>
    

    对于非空匹配元素,这种情况是正确的,但是会避免要求计算当前节点的字符串值(无论如何你真的不需要)。

答案 1 :(得分:1)

在xslt 2.0中我会做这样的事情:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes"/>

    <xsl:key name="element-by-name" match="element" use="@name"/>

    <xsl:variable name="acceptedElements">
        <element name="a1"/>
        <element name="a3"/>
        <element name="a5"/>
    </xsl:variable>

    <xsl:template match="*">
        <xsl:if test="key('element-by-name', local-name(), $acceptedElements)">
            <xsl:value-of select="local-name()"/>
        </xsl:if>
        <xsl:apply-templates select="*"/>
    </xsl:template>
</xsl:stylesheet>