2011-04-11 19 views
1

我有一個XML文件:如何在多個級別進行分組?

<document> 
    <line id="0"> 
     <field id="2">X111</field> 
     <field id="3">1</field> 
     <field id="4">222222222222</field> 
    </line> 
    <line id="1"> 
     <field id="2">X111</field> 
     <field id="3">1</field> 
     <field id="4">111111111111</field> 
    </line> 
    <line id="2"> 
     <field id="2">X222</field> 
     <field id="3">1</field> 
     <field id="4">111111111111</field> 
    </line> 
    <line id="3"> 
     <field id="2">X222</field> 
     <field id="3">1></field> 
     <field id="4">111111111111</field> 
    </line> 
    <line id="4"> 
     <field id="2">X333</field> 
     <field id="3">1</field> 
     <field id="4">111111111111</field> 
    </line> 
</document> 

從這個xml文件,我應該組域2(即字段4後),問題將是不如何將欄位2,並得到三個文件,但如何分組字段4,如果他們是相同的?

輸出:

<document> 
<Result> 
    <Header> 
     <Field2>X111</Field2> 
    </Header> 
    <Line> 
     <Position>1</Position> 
     <Field4>222222222222</Field4> 
     <Sum>1<Sum> 
     <Position>2</Position> 
     <Field4>111111111111</Field4> 
     <Sum>1<Sum> 
    </Line> 
</Result> 
<Result> 
    <Header> 
     <Field2>X222</Field2> 
    </Header> 
    <Line> 
     <Position>1</Position> 
     <Field4>111111111111</Field4> 
     <Sum>2<Sum> 
    </Line> 
</Result> 
<Result> 
    <Header> 
     <Field2>X333</Field2> 
    </Header> 
    <Line> 
     <Position>1</Position> 
     <Field4>111111111111</Field4> 
     <Sum>1</Sum> 
    </Line> 
</Result> 
</document> 

我被困在分組行,我不知道該相同和不同領域如何組ID = 4

我的程序看起來其中:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/> 
    <xsl:key name="kLine" match="line" use="string(field[@id=2])"/> 
    <xsl:key name="bLine" match="line" use="field[@id=4]"/> 
    <xsl:template match="document"> 
     <document> 
      <xsl:apply-templates select="line[count(. | key('kLine', string(field[@id='2']))[1]) = 1]"/> 
     </document> 
    </xsl:template> 
    <xsl:template match="line"> 
     <xsl:variable name="field2" select="field[@id='2']"/> 
     <result> 
      <Header> 
       <xsl:value-of select="field[@id='2']"/> 
      </Header> 
      <Line> 
      <xsl:for-each select="//line[field[@id='2']=$field2]"> 
       <Position> 
        <xsl:value-of select="position()"/> 
       </Position> 
       <Field4><xsl:value-of select="field[@id='4']"/></Field4> 
       <Sum><xsl:value-of select="sum(key('bLine', field[@id='4'])/field[@id='3'])"/></Sum> 
      </xsl:for-each> 
      </Line> 
     </result> 
    </xsl:template> 
</xsl:stylesheet> 

回答

1

你在問怎麼在多個層次上組合。下面的樣式表:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:key name="byField2" match="line" use="field[@id='2']" /> 
    <xsl:key name="byField2AndField4" match="line" 
      use="concat(field[@id='2'], '|', field[@id='4'])" /> 
    <xsl:template match="/"> 
     <document><xsl:apply-templates /></document> 
    </xsl:template> 
    <xsl:template 
     match="line[generate-id() = 
        generate-id(key('byField2', field[@id='2'])[1])]"> 
     <Result> 
      <Header> 
       <Field2><xsl:value-of select="field[@id='2']" /></Field2> 
      </Header> 
      <Line> 
       <xsl:apply-templates 
        select="key('byField2', field[@id='2']) 
         [generate-id() = 
          generate-id(key('byField2AndField4', 
          concat(field[@id='2'], '|', field[@id='4']))[1])]" 
        mode="field4" /> 
      </Line> 
     </Result> 
    </xsl:template> 
    <xsl:template match="line" mode="field4"> 
     <Position><xsl:value-of select="position()" /></Position> 
     <Field4><xsl:value-of select="field[@id='4']" /></Field4> 
     <Sum> 
      <xsl:value-of 
       select="sum(key('byField2AndField4', 
       concat(field[@id='2'], '|', field[@id='4']))/ 
        field[@id='3'])" /> 
     </Sum> 
    </xsl:template> 
    <xsl:template match="line" /> 
</xsl:stylesheet> 

在此輸入:

<document> 
    <line id="0"> 
     <field id="2">X111</field> 
     <field id="3">1</field> 
     <field id="4">222222222222</field> 
    </line> 
    <line id="1"> 
     <field id="2">X111</field> 
     <field id="3">1</field> 
     <field id="4">111111111111</field> 
    </line> 
    <line id="2"> 
     <field id="2">X222</field> 
     <field id="3">1</field> 
     <field id="4">111111111111</field> 
    </line> 
    <line id="3"> 
     <field id="2">X222</field> 
     <field id="3">1></field> 
     <field id="4">111111111111</field> 
    </line> 
    <line id="4"> 
     <field id="2">X333</field> 
     <field id="3">1</field> 
     <field id="4">111111111111</field> 
    </line> 
</document> 

生成所需的結果:

<document> 
    <Result> 
     <Header> 
      <Field2>X111</Field2> 
     </Header> 
     <Line> 
      <Position>1</Position> 
      <Field4>222222222222</Field4> 
      <Sum>1</Sum> 
      <Position>2</Position> 
      <Field4>111111111111</Field4> 
      <Sum>1</Sum> 
     </Line> 
    </Result> 
    <Result> 
     <Header> 
      <Field2>X222</Field2> 
     </Header> 
     <Line> 
      <Position>1</Position> 
      <Field4>111111111111</Field4> 
      <Sum>2</Sum> 
     </Line> 
    </Result> 
    <Result> 
     <Header> 
      <Field2>X333</Field2> 
     </Header> 
     <Line> 
      <Position>1</Position> 
      <Field4>111111111111</Field4> 
      <Sum>1</Sum> 
     </Line> 
    </Result> 
</document> 

我們使用兩個密鑰。第一組僅由字段2組成。第二組由字段2和4串聯組成。

+0

@lwburk:在第二個鍵選擇中缺少一個'[1]'謂詞。 – 2011-04-11 16:33:13

+0

@Alejandro - 有趣的你應該提到它。我注意到,幾分鐘前,並感到驚訝,它在我以前的測試工作。重新閱讀規範,我發現'generate-id'以文檔順序返回集合中第一個節點的ID,這就是爲什麼它仍然按預期工作。包含額外的'[1]'謂詞是否有一些優勢? – 2011-04-11 16:51:17

+1

@lwburk:除了可讀性以外的其他原因是節點集隱式轉換爲單例不是XPath 2.0的一部分,因此會引發錯誤。這是一件好事,因爲靜默隱式投射可能會隱藏一些邏輯錯誤。 – 2011-04-11 17:00:33

相關問題