2013-10-14 114 views
0

我想組下面的XML:分組XML元素

<?xml version="1.0" encoding="UTF-8"?> 
<EDIFACT segmentDelimiter="&#39;" itemDelimiter="+" elementDelimiter=":" decimalCharacter="." escapeCharacter="?"> 
    <Envelope count='1'> 
     <UNB> 
      <I1> 
       <E1>UNOA</E1> 
       <E2>2</E2> 
      </I1> 
     </UNB> 
     <Message count='1'> 
      <UNH> 
       <I1> 
        <E1>8351519</E1> 
       </I1> 
       <I2> 
        <E1>MESTYP</E1> 
        <E2>D</E2> 
        <E3>96A</E3> 
        <E4>UN</E4> 
       </I2> 
      </UNH> 
      <BGM> 
       <I1> 
        <E1>351</E1> 
       </I1> 
       <I2> 
        <E1>8351519</E1> 
       </I2> 
      </BGM> 
      <DTM> 
       <I1> 
        <E1>137</E1> 
        <E2>20130429</E2> 
        <E3>102</E3> 
       </I1> 
      </DTM> 
      <DTM> 
       <I1> 
        <E1>132</E1> 
        <E2>20130521</E2> 
        <E3>102</E3> 
       </I1> 
      </DTM> 
      <CPS> 
       <I1> 
        <E1>1</E1> 
       </I1> 
      </CPS> 
      <LIN> 
       <I1> 
        <E1/> 
       </I1> 
       <I2> 
        <E1/> 
       </I2> 
       <I3> 
        <E1>859700015000</E1> 
       </I3> 
      </LIN> 
      <QTY> 
       <I1> 
        <E1>12</E1> 
        <E2>305</E2> 
       </I1> 
      </QTY> 
      <SGP> 
       <I1> 
        <E1>KA02</E1> 
        <E2>129</E2> 
       </I1> 
      </SGP> 
      <SGP> 
       <I1> 
        <E1>0001</E1> 
        <E2>156</E2> 
       </I1> 
      </SGP> 
      <SGP> 
       <I1> 
        <E1>1ST CHOICE</E1> 
        <E2>189</E2> 
       </I1> 
      </SGP> 
      <CPS> 
       <I1> 
        <E1>2</E1> 
       </I1> 
      </CPS> 
      <LIN> 
       <I1> 
        <E1/> 
       </I1> 
       <I2> 
        <E1/> 
       </I2> 
       <I3> 
        <E1>859700015010</E1> 
       </I3> 
      </LIN> 
      <QTY> 
       <I1> 
        <E1>12</E1> 
        <E2>424</E2> 
       </I1> 
      </QTY> 
      <SGP> 
       <I1> 
        <E1>KA02</E1> 
        <E2>129</E2> 
       </I1> 
      </SGP> 
      <SGP> 
       <I1> 
        <E1>0001</E1> 
        <E2>156</E2> 
       </I1> 
      </SGP> 
      <SGP> 
       <I1> 
        <E1>1ST CHOICE</E1> 
        <E2>189</E2> 
       </I1> 
      </SGP> 
      <UNT> 
       <I1> 
        <E1>89</E1> 
       </I1> 
       <I2> 
        <E1>8351519</E1> 
       </I2> 
      </UNT> 
     </Message> 
     <UNZ> 
      <I1> 
       <E1>1</E1> 
      </I1> 
      <I2> 
       <E1>8351519</E1> 
      </I2> 
     </UNZ> 
    </Envelope> 
</EDIFACT> 

我試圖讓下面的輸出:

<?xml version="1.0" encoding="UTF-8"?> 
<EDIFACT segmentDelimiter="'" itemDelimiter="+" elementDelimiter=":" decimalCharacter="." escapeCharacter="?"> 
    <Envelope count="1"> 
     <UNB> 
      <I1> 
       <E1>UNOA</E1> 
       <E2>2</E2> 
      </I1> 
     </UNB> 
     <Message count="1"> 
      <UNH> 
       <I1> 
        <E1>8351519</E1> 
       </I1> 
       <I2> 
        <E1>MESTYP</E1> 
        <E2>D</E2> 
        <E3>96A</E3> 
        <E4>UN</E4> 
       </I2> 
      </UNH> 
      <BGM> 
       <I1> 
        <E1>351</E1> 
       </I1> 
       <I2> 
        <E1>8351519</E1> 
       </I2> 
      </BGM> 
      <DTM> 
       <I1> 
        <E1>137</E1> 
        <E2>20130429</E2> 
        <E3>102</E3> 
       </I1> 
      </DTM> 
      <DTM> 
       <I1> 
        <E1>132</E1> 
        <E2>20130521</E2> 
        <E3>102</E3> 
       </I1> 
      </DTM> 
      <articleLine> 
       <CPS> 
        <I1> 
         <E1>1</E1> 
        </I1> 
       </CPS> 
       <LIN> 
        <I1> 
         <E1/> 
        </I1> 
        <I2> 
         <E1/> 
        </I2> 
        <I3> 
         <E1>859700015000</E1> 
        </I3> 
       </LIN> 
       <QTY> 
        <I1> 
         <E1>12</E1> 
         <E2>305</E2> 
        </I1> 
       </QTY> 
       <SGP> 
        <I1> 
         <E1>KA02</E1> 
         <E2>129</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>0001</E1> 
         <E2>156</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>1ST CHOICE</E1> 
         <E2>189</E2> 
        </I1> 
       </SGP> 
      </articleLine> 
      <articleLine> 
       <CPS> 
        <I1> 
         <E1>2</E1> 
        </I1> 
       </CPS> 
       <LIN> 
        <I1> 
         <E1/> 
        </I1> 
        <I2> 
         <E1/> 
        </I2> 
        <I3> 
         <E1>859700015010</E1> 
        </I3> 
       </LIN> 
       <QTY> 
        <I1> 
         <E1>12</E1> 
         <E2>424</E2> 
        </I1> 
       </QTY> 
       <SGP> 
        <I1> 
         <E1>KA02</E1> 
         <E2>129</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>0001</E1> 
         <E2>156</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>1ST CHOICE</E1> 
         <E2>189</E2> 
        </I1> 
       </SGP> 
      </articleLine> 
      <articleLine> 
       <CPS> 
        <I1> 
         <E1>3</E1> 
        </I1> 
       </CPS> 
       <LIN> 
        <I1> 
         <E1/> 
        </I1> 
        <I2> 
         <E1/> 
        </I2> 
        <I3> 
         <E1>859700015100</E1> 
        </I3> 
       </LIN> 
       <QTY> 
        <I1> 
         <E1>12</E1> 
         <E2>139</E2> 
        </I1> 
       </QTY> 
       <SGP> 
        <I1> 
         <E1>KA02</E1> 
         <E2>129</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>0001</E1> 
         <E2>156</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>1ST CHOICE</E1> 
         <E2>189</E2> 
        </I1> 
       </SGP> 
      </articleLine> 
      <articleLine> 
       <CPS> 
        <I1> 
         <E1>4</E1> 
        </I1> 
       </CPS> 
       <LIN> 
        <I1> 
         <E1/> 
        </I1> 
        <I2> 
         <E1/> 
        </I2> 
        <I3> 
         <E1>859700015130</E1> 
        </I3> 
       </LIN> 
       <QTY> 
        <I1> 
         <E1>12</E1> 
         <E2>100</E2> 
        </I1> 
       </QTY> 
       <SGP> 
        <I1> 
         <E1>KA02</E1> 
         <E2>129</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>0001</E1> 
         <E2>156</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>1ST CHOICE</E1> 
         <E2>189</E2> 
        </I1> 
       </SGP> 
      </articleLine> 
      <articleLine> 
       <CPS> 
        <I1> 
         <E1>5</E1> 
        </I1> 
       </CPS> 
       <LIN> 
        <I1> 
         <E1/> 
        </I1> 
        <I2> 
         <E1/> 
        </I2> 
        <I3> 
         <E1>859700015180</E1> 
        </I3> 
       </LIN> 
       <QTY> 
        <I1> 
         <E1>12</E1> 
         <E2>55</E2> 
        </I1> 
       </QTY> 
       <SGP> 
        <I1> 
         <E1>KA02</E1> 
         <E2>129</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>0001</E1> 
         <E2>156</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>1ST CHOICE</E1> 
         <E2>189</E2> 
        </I1> 
       </SGP> 
      </articleLine> 
      <articleLine> 
       <CPS> 
        <I1> 
         <E1>6</E1> 
        </I1> 
       </CPS> 
       <LIN> 
        <I1> 
         <E1/> 
        </I1> 
        <I2> 
         <E1/> 
        </I2> 
        <I3> 
         <E1>859700015200</E1> 
        </I3> 
       </LIN> 
       <QTY> 
        <I1> 
         <E1>12</E1> 
         <E2>50</E2> 
        </I1> 
       </QTY> 
       <SGP> 
        <I1> 
         <E1>KA02</E1> 
         <E2>129</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>0001</E1> 
         <E2>156</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>1ST CHOICE</E1> 
         <E2>189</E2> 
        </I1> 
       </SGP> 
      </articleLine> 
      <articleLine> 
       <CPS> 
        <I1> 
         <E1>7</E1> 
        </I1> 
       </CPS> 
       <LIN> 
        <I1> 
         <E1/> 
        </I1> 
        <I2> 
         <E1/> 
        </I2> 
        <I3> 
         <E1>859700515230</E1> 
        </I3> 
       </LIN> 
       <QTY> 
        <I1> 
         <E1>12</E1> 
         <E2>13</E2> 
        </I1> 
       </QTY> 
       <SGP> 
        <I1> 
         <E1>KA02</E1> 
         <E2>129</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>0001</E1> 
         <E2>156</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>1ST CHOICE</E1> 
         <E2>189</E2> 
        </I1> 
       </SGP> 
      </articleLine> 
      <articleLine> 
       <CPS> 
        <I1> 
         <E1>8</E1> 
        </I1> 
       </CPS> 
       <LIN> 
        <I1> 
         <E1/> 
        </I1> 
        <I2> 
         <E1/> 
        </I2> 
        <I3> 
         <E1>859700015240</E1> 
        </I3> 
       </LIN> 
       <QTY> 
        <I1> 
         <E1>12</E1> 
         <E2>5</E2> 
        </I1> 
       </QTY> 
       <SGP> 
        <I1> 
         <E1>KA02</E1> 
         <E2>129</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>0001</E1> 
         <E2>156</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>1ST CHOICE</E1> 
         <E2>189</E2> 
        </I1> 
       </SGP> 
      </articleLine> 
      <articleLine> 
       <CPS> 
        <I1> 
         <E1>9</E1> 
        </I1> 
       </CPS> 
       <LIN> 
        <I1> 
         <E1/> 
        </I1> 
        <I2> 
         <E1/> 
        </I2> 
        <I3> 
         <E1>859700015260</E1> 
        </I3> 
       </LIN> 
       <QTY> 
        <I1> 
         <E1>12</E1> 
         <E2>105</E2> 
        </I1> 
       </QTY> 
       <SGP> 
        <I1> 
         <E1>KA02</E1> 
         <E2>129</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>0001</E1> 
         <E2>156</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>1ST CHOICE</E1> 
         <E2>189</E2> 
        </I1> 
       </SGP> 
      </articleLine> 
      <articleLine> 
       <CPS> 
        <I1> 
         <E1>10</E1> 
        </I1> 
       </CPS> 
       <LIN> 
        <I1> 
         <E1/> 
        </I1> 
        <I2> 
         <E1/> 
        </I2> 
        <I3> 
         <E1>859700015300</E1> 
        </I3> 
       </LIN> 
       <QTY> 
        <I1> 
         <E1>12</E1> 
         <E2>75</E2> 
        </I1> 
       </QTY> 
       <SGP> 
        <I1> 
         <E1>KA02</E1> 
         <E2>129</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>0001</E1> 
         <E2>156</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>1ST CHOICE</E1> 
         <E2>189</E2> 
        </I1> 
       </SGP> 
      </articleLine> 
      <articleLine> 
       <CPS> 
        <I1> 
         <E1>11</E1> 
        </I1> 
       </CPS> 
       <LIN> 
        <I1> 
         <E1/> 
        </I1> 
        <I2> 
         <E1/> 
        </I2> 
        <I3> 
         <E1>859700015360</E1> 
        </I3> 
       </LIN> 
       <QTY> 
        <I1> 
         <E1>12</E1> 
         <E2>28</E2> 
        </I1> 
       </QTY> 
       <SGP> 
        <I1> 
         <E1>KA02</E1> 
         <E2>129</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>0001</E1> 
         <E2>156</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>1ST CHOICE</E1> 
         <E2>189</E2> 
        </I1> 
       </SGP> 
      </articleLine> 
      <articleLine> 
       <CPS> 
        <I1> 
         <E1>12</E1> 
        </I1> 
       </CPS> 
       <LIN> 
        <I1> 
         <E1/> 
        </I1> 
        <I2> 
         <E1/> 
        </I2> 
        <I3> 
         <E1>859700515370</E1> 
        </I3> 
       </LIN> 
       <QTY> 
        <I1> 
         <E1>12</E1> 
         <E2>10</E2> 
        </I1> 
       </QTY> 
       <SGP> 
        <I1> 
         <E1>KA02</E1> 
         <E2>129</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>0001</E1> 
         <E2>156</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>1ST CHOICE</E1> 
         <E2>189</E2> 
        </I1> 
       </SGP> 
      </articleLine> 
      <articleLine> 
       <CPS> 
        <I1> 
         <E1>13</E1> 
        </I1> 
       </CPS> 
       <LIN> 
        <I1> 
         <E1/> 
        </I1> 
        <I2> 
         <E1/> 
        </I2> 
        <I3> 
         <E1>859700016030</E1> 
        </I3> 
       </LIN> 
       <QTY> 
        <I1> 
         <E1>12</E1> 
         <E2>35</E2> 
        </I1> 
       </QTY> 
       <SGP> 
        <I1> 
         <E1>KA02</E1> 
         <E2>129</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>0001</E1> 
         <E2>156</E2> 
        </I1> 
       </SGP> 
       <SGP> 
        <I1> 
         <E1>1ST CHOICE</E1> 
         <E2>189</E2> 
        </I1> 
       </SGP> 
      </articleLine> 
      <UNT> 
       <I1> 
        <E1>89</E1> 
       </I1> 
       <I2> 
        <E1>8351519</E1> 
       </I2> 
      </UNT> 
     </Message> 
     <UNZ> 
      <I1> 
       <E1>1</E1> 
      </I1> 
      <I2> 
       <E1>8351519</E1> 
      </I2> 
     </UNZ> 
    </Envelope> 
</EDIFACT> 

我目前使用的XSLT:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="fn xs"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

    <!-- Identity template (copies all nodes and attributes) --> 
    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*" /> 
     </xsl:copy> 
    </xsl:template> 

     <!-- When 'Message' node is found, do following --> 
    <xsl:template match="Message"> 
     <!-- Copy 'Message' node itself --> 
     <xsl:copy> 
      <!-- Also copy attributes of 'Message' node --> 
      <xsl:apply-templates select="@*" /> 

      <!-- Group by CPS nodes --> 
      <xsl:for-each-group select="*" group-starting-with="CPS"> 
       <!-- Before any CPS node, put a articleLine node (UNH gets included also at this moment and UNT) --> 
       <articleLine> 
        <xsl:apply-templates select="current-group()" /> 
       </articleLine> 
      </xsl:for-each-group> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

我面臨的問題是,我的結果中的第一組是第一個CPS元素之前的所有內容。我不想將此添加到名爲「articleLine」的組中。還在最後一個小組中增加了UNT,這應該是'articleLine'的一部分。

我可以使用xsl:for-each-group?或者我應該自定義分組嗎?


**編輯** 當我使用下面的模板:

<!-- When 'Message' node is found, do following --> 
<xsl:template match="Message"> 
    <!-- Copy 'Message' node itself --> 
    <xsl:copy> 
     <!-- Also copy attributes of 'Message' node --> 
     <xsl:apply-templates select="@*" /> 

     <!--xsl:copy-of select="UNH|BGM|DTM"/--> 
     <xsl:copy-of select="CPS[1]/preceding-sibling::*" /> 

     <!-- Group by CPS nodes --> 
     <xsl:for-each-group select="CPS[1]/following-sibling::*[name()!='UNT']" group-starting-with="CPS"> 
      <!-- Before any CPS node, put a articleLine node (UNH gets included also at this moment) --> 
      <articleLine> 
       <xsl:apply-templates select="current-group()" /> 
      </articleLine> 
     </xsl:for-each-group> 

     <xsl:copy-of select="UNT" /> 
    </xsl:copy> 
</xsl:template> 

這幾乎是正確的。我只想念結果中的第一個CPS元素。

回答

1

當使用group-starting-with,避免包裝不屬於一組元素,我會建議使用

<xsl:template match="Message"> 
    <!-- Copy 'Message' node itself --> 
    <xsl:copy> 
     <!-- Also copy attributes of 'Message' node --> 
     <xsl:apply-templates select="@*" /> 

     <!-- Group by CPS nodes --> 
     <xsl:for-each-group select="*" group-starting-with="CPS"> 
      <!-- Before any CPS node, put a articleLine node (UNH gets included also at this moment and UNT) --> 
      <xsl:choose> 
       <xsl:when test="self::CPS"> 
       <articleLine> 
        <xsl:apply-templates select="current-group()" /> 
       </articleLine> 
       </xsl:when> 
       <xsl:otherwise> 
       <xsl:apply-templates select="current-group()"/> 
       </xsl:otherwise> 
      </xsl:choose> 
     </xsl:for-each-group> 
    </xsl:copy> 
</xsl:template> 

如果你不想組UNT元素,然後用

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" exclude-result-prefixes="fn xs"> 
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

    <!-- Identity template (copies all nodes and attributes) --> 
    <xsl:template match="node()|@*"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()|@*" /> 
     </xsl:copy> 
    </xsl:template> 

     <!-- When 'Message' node is found, do following --> 
    <xsl:template match="Message"> 
     <!-- Copy 'Message' node itself --> 
     <xsl:copy> 
      <!-- Also copy attributes of 'Message' node --> 
      <xsl:apply-templates select="@*" /> 

      <!-- Group by CPS nodes --> 
      <xsl:for-each-group select="* except UNT" group-starting-with="CPS"> 
       <!-- Before any CPS node, put a articleLine node (UNH gets included also at this moment and UNT) --> 
       <xsl:choose> 
        <xsl:when test="self::CPS"> 
        <articleLine> 
         <xsl:apply-templates select="current-group()" /> 
        </articleLine> 
        </xsl:when> 
        <xsl:otherwise> 
        <xsl:apply-templates select="current-group()"/> 
        </xsl:otherwise> 
       </xsl:choose> 
      </xsl:for-each-group> 

      <xsl:apply-templates select="UNT"/> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet>