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>

for each の使用を最小限に抑えて、以下のようなターゲット コレクションが必要です。

<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 倍にトラバースする変換が行われ、システム パフォーマンスに影響を与えています。これを回避するためのアイデアを教えてください。

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 に答える