我有源集合如下。
<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次的力量,这就达到了系统性能。 请让我知道任何想法,以避免这种情况。
答案 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>