Xsl 转换优化

Posted

技术标签:

【中文标题】Xsl 转换优化【英文标题】:Xsl transformation optimization 【发布时间】:2013-12-02 20:36:49 【问题描述】:

我有两个 xml 文件:

products.xml

<lists>
<list id="0">
      <group id="53149">
        <product id="87563223"/>
        <product id="25000016"/>
      </group>
      <group id="138939">
        <product id="2400004"/>
        <product id="2400005"/>
      </group>
</list>
<list id="1">
      <group id="34181">
        <product id="2249213"/>
      </group>
      <group id="73892">
        <product id="1306005"/>
        <product id="9300001"/>
      </group>
</list>
</lists>

和valid_products.xml

<ValidProducts>
  <product>
     <ID>1306005</ID>
  </product>
  <product>
     <ID>87563223</ID>
  </product>
</ValidProducts>

我正在使用 xslt 和 Saxon-HE 处理器从第一个文件中删除产品,其中 id 与第二个文件中提供的 id 不匹配

结果 xml:

<lists>
<list id="0">
      <group id="53149">
        <product id="87563223"/>
      </group>
      <group id="138939">
      </group>
</list>
<list id="1">
      <group id="34181">
      </group>
      <group id="73892">
        <product id="1306005"/>
      </group>
</list>
</lists>

这是我的 xsl:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml" version="2.0">     
    <xsl:output indent="no"/>
    <xsl:strip-space elements="*"/>
    <xsl:param name="f1" />
    <xsl:variable name="doc1" select="document($f1)"/>

    <xsl:variable name="valids" select="$doc1/ValidProducts/product/ID/text()" />

    <xsl:template match="@* | node()"> 
        <xsl:copy> 
            <xsl:apply-templates select="@* | node()"/> 
        </xsl:copy> 
    </xsl:template>  
    <xsl:template match="/lists/list//product[@id[not(. = $valids)]]"/>
</xsl:stylesheet>

我将第二个文件作为参数传递给 xsl 样式表,它工作正常,但对于大文件(超过 200mb),它真的很慢,我该如何优化它?

【问题讨论】:

【参考方案1】:

使用密钥:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml" version="2.0">     
    <xsl:output indent="no"/>
    <xsl:strip-space elements="*"/>
    <xsl:param name="f1" />
    <xsl:variable name="doc1" select="document($f1)"/>

    <xsl:key name="by-id" match="ValidProducts/product" use="ID"/>


    <xsl:template match="@* | node()"> 
        <xsl:copy> 
            <xsl:apply-templates select="@* | node()"/> 
        </xsl:copy> 
    </xsl:template>  

    <xsl:template match="/lists/list//product[not(key('by-id', @id, $doc1))]"/>
</xsl:stylesheet>

【讨论】:

请注意,Saxon-EE 会自动为您执行此优化,但正如您所发现的,手动执行并不难!

以上是关于Xsl 转换优化的主要内容,如果未能解决你的问题,请参考以下文章

Jmeter报告优化之New XSL stylesheet

转换 XSL

xsl 转换在 .net 环境中生成 xsl 样式表

转换前更新 XSL 文件

XSL 转换以输出许多嵌入式 XSL 样式表

如何解决从字符串加载 XSL 的转换中包含的 XSL?