2014-03-07 34 views
0

我想做一個XSL轉換,其中我想要組類似的東西。如何使用XSLT對處於同一級別的XML數據進行分組?

但隨着像「鑰匙」方法「產生-ID」我不能夠實現這一目標。

我把源和低於預期的格式。

我也看看this。所以思想與爲了簡化同樣的例子的

來源:

<Root><!-- yes, I know I don't need a 'Root' element! Legacy code... --> 
    <Plans> 
    <Planner id="1"> 
    <Plan AreaID="1"></Plan> 
     <Part ID="9122" Name="foo" /> 
     <Part ID="9126" Name="bar" /> 
    <Plan AreaID="1"></Plan> 
     <Part ID="8650" Name="baz" /> 
    <Plan AreaID="2"></Plan> 
     <Part ID="215" Name="quux" /> 
    <Plan AreaID="1" ></Plan> 
     <Part ID="7350" Name="meh" /> 
    </Planner> 

    <Planner id="2"> 
    <Plan AreaID="1"></Plan> 
     <Part ID="9122" Name="foo" /> 
     <Part ID="9126" Name="bar" /> 
    <Plan AreaID="1"></Plan> 
     <Part ID="8650" Name="baz" /> 
    <Plan AreaID="2"></Plan> 
     <Part ID="215" Name="quux" /> 
    <Plan AreaID="1" ></Plan> 
     <Part ID="7350" Name="meh" /> 
    </Planner> 
    </Plans> 
</Root> 

預計:

<Root><!-- yes, I know I don't need a 'Root' element! Legacy code... --> 
    <Plans> 
     <Planner id="1"> 
      <Plan AreaID="1"></Plan> 
      <Part ID="9122" Name="foo" /> 
      <Part ID="9126" Name="bar" /> 
      <Part ID="8650" Name="baz" /> 
      <Part ID="7350" Name="meh" /> 
      <Plan AreaID="2"></Plan> 
      <Part ID="215" Name="quux" /> 
     </Planner> 

     <Planner id="2"> 
      <Plan AreaID="1"></Plan> 
      <Part ID="9122" Name="foo" /> 
      <Part ID="9126" Name="bar" /> 
      <Part ID="8650" Name="baz" /> 
      <Part ID="7350" Name="meh" /> 
      <Plan AreaID="2"></Plan> 
      <Part ID="215" Name="quux" /> 
     </Planner> 
    </Plans> 
</Root> 

在我的情況下,由於規劃和部分處於同一水平,我沒有能集團根據我想要做的理想計劃。

+2

到分組(和許多其他)問題的解決方案依賴於是否使用XSLT 1.0或XSLT 2.0。請隨時說出您正在使用的是哪個版本。 –

回答

4

的竅門能讓Muenchian分組的在這種情況下,你要組一個特定父之內,而不是在全球範圍內的工作,是包括唯一父的東西作爲分組鍵的一部分。通常,您可以使用generate-id(..),但在這種情況下,您可以簡單地使用Planner以外的id屬性。例如

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:strip-space elements="*" /> 
    <xsl:output indent="yes" /> 

    <xsl:key name="partByArea" match="Part" 
    use="concat(../@id, '|', preceding-sibling::Plan[1]/@AreaID)" /> 

    <!-- identity template - copy everything as-is except when overridden --> 
    <xsl:template match="@*|node()"> 
    <xsl:copy><xsl:apply-templates select="@*|node()" /></xsl:copy> 
    </xsl:template> 

    <xsl:template match="Planner"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*" /> 
     <!-- select the first Part in each group --> 
     <xsl:apply-templates mode="group" select="Part[generate-id() = 
     generate-id(key('partByArea', 
     concat(current()/@id, '|', preceding-sibling::Plan[1]/@AreaID))[1])]" /> 
    </xsl:copy> 
    </xsl:template> 

    <!-- template applied to the first Part in each group --> 
    <xsl:template match="Part" mode="group"> 
    <!-- the Plan that heads this group --> 
    <xsl:apply-templates select="preceding-sibling::Plan[1]" /> 
    <!-- all the matching Part elements --> 
    <xsl:apply-templates select="key('partByArea', 
     concat(../@id, '|', preceding-sibling::Plan[1]/@AreaID))" /> 
    </xsl:template> 
</xsl:stylesheet> 

這裏我們通過分組其父Plannerid的組合Part元件和其最接近的前面的PlanAreaID

+0

你能分享XSL嗎?分組時我非常困惑。 – Sam

+0

@Sam我已經添加了一個可以實現您之後映射的方法示例。 –

相關問題