XSLT-试图避免每次循环

时间:2013-05-24 01:08:31

标签: xslt-1.0 bpel

我有源集合如下。

<SourceCollection>
<Row1>
 <Col1>Store1</Col1>
 <Col2>Med1</Col2>
    <Col3>Val1</Col3>
</Row1>
<Row2>
 <Col1>Store1</Col1>
    <Col2>Med1</Col2>
      <Col3>Val2</Col3>
</Row2>
<Row3>
<Col1>Store1</Col1>
    <Col2>Med2</Col2>
        <Col3>Val2</Col3>
</Row3>
<Row4>
<Col1>Store2</Col1>
     <Col2>Med1</Col2>
        <Col3>Val4</Col3>
</Row4>
</SourceCollection>

我希望目标集合如下所示,每个目标集合的使用率最低。

<TargetCollection>
<Store value=Store1>
 <Dim value=Med1>
              <DimCode>Val1</DimCode>
              <DimCode>Val2</DimCode>
     </Dim>
     <Dim value=Med2>
              <DimCode>Val3</DimCode>
     </Dim>
</Store>
<Store value=Store2>
     <Dim value=Med1>
              <DimCode>Val4</DimCode>
     </Dim>
</Store>
</TargetCollection>  `

在我的初始设计中,我在同一个源集合上使用了3个for-each循环,以根据需要形成目标xml。但是,源集合包含数百万行,这使我的转换遍历整个列表(行)到3次的力量,这就达到了系统性能。 请让我知道任何想法,以避免这种情况。

1 个答案:

答案 0 :(得分:2)

通常,使用xsl:key可以帮助加快转换速度。尝试这样的事情:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:output indent="yes"/>

    <xsl:key name="Col1" match="Col1" use="."/>
    <xsl:key name="Col2byCol1" match="Col2" use="concat(../Col1, '-', .)"/>
    <xsl:key name="Col3byCol1andCol2" 
                  match="Col3" use="concat(../Col1, '-', ../Col2, '-', .)"/>

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

    <xsl:template match="SourceCollection">
        <TargetCollection>
            <xsl:apply-templates 
                    select="*/Col1[generate-id() = 
                                   generate-id(key(local-name(), .)[1])]"/>
        </TargetCollection>
    </xsl:template>    

    <xsl:template match="Col1">
        <xsl:variable name="Column1" select="."/>
        <Store value="{.}">
            <xsl:apply-templates select="../../*/Col2[generate-id() = 
                generate-id(key('Col2byCol1', concat($Column1, '-' ,.))[1])]"/>
        </Store>
    </xsl:template>

    <xsl:template match="Col2">
        <xsl:variable name="Column1" select="../Col1"/>
        <xsl:variable name="Column2" select="."/>

        <Dim value="{.}">
            <xsl:apply-templates 
                   select="../../*[Col2=$Column2]/Col3[generate-id() = 
                          generate-id(key('Col3byCol1andCol2', 
                                   concat($Column1, '-', $Column2, '-',.)))]"/>
        </Dim>
    </xsl:template>

    <xsl:template match="Col3">
        <DimCode value="{.}">
            <xsl:apply-templates />
        </DimCode>
    </xsl:template>

</xsl:stylesheet>