3

我的源集合如下。

<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。但是,源集合包含数百万行,这使我转换为遍历整个列表(Rows)的 3 次幂,这对系统性能造成了打击。请让我知道避免这种情况的任何想法。

4

1 回答 1

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>
于 2013-05-24T02:28:44.060 回答