2013-04-30 4 views
0

У меня есть файл xml, который необходимо преобразовать в иерархический. Я использовал идею вложенной группировки здесь. Необходима помощь xsl: for-each-group. Он работает по большей части, за исключением нескольких вопросов:xsl: for-each-group позиционная группировка flat xml для иерархического

1) Элементы root1 и root2 не отображаются.

2) Неверное расположение элемента NFActy. Первый NFActy должен быть между 2 элементами Rot.

3) Duty & Элементы NFActy рассматриваются как одна группа для расчета SequenceCount.

4) Для элементов ног каждый комплект элементов ноги в пределах одной обязанности должен быть сгруппирован для последовательности SequenceCount для элементов ноги.

Любая помощь действительно оценена.

Спасибо.

Входной XML

<root> 
<root1>1234</root1> 
<root2>5678</root2> 
<Schedule> 
    <a>line 1</a> 
    <b>line 2</b> 
    <c>line 3</c> 
</Schedule> 
<Rot> 
    <d>line 4</d> 
    <e>line 5</e> 
    <f>line 6</f> 
    <g>line 7</g> 
</Rot> 
<Duty> 
    <h>line 8</h> 
    <i>line 9</i> 
    <j>line 10</j> 
    <k>line 11</k> 
    <l>line 12</l> 
</Duty> 
<Leg> 
    <m>line 13</m> 
    <n>line 14</n> 
    <o>line 15</o> 
</Leg> 
<Leg> 
    <m>line 13</m> 
    <n>line 14</n> 
    <o>line 15</o> 
</Leg> 
<NFActy> 
    <d>line 214</d> 
    <e>line 215</e> 
    <f>line 216</f> 
    <g>line 217</g> 
</NFActy> 
<Rot> 
    <d>line 19</d> 
    <e>line 20</e> 
    <f>line 21</f> 
    <g>line 22</g> 
</Rot> 
<Duty> 
    <h>line 23</h> 
    <i>line 24</i> 
    <j>line 25</j> 
    <k>line 26</k> 
    <l>line 27</l> 
</Duty> 
<Leg> 
    <m>line 28</m> 
    <n>line 29</n> 
    <o>line 30</o> 
</Leg> 
<Leg> 
    <m>line 13</m> 
    <n>line 14</n> 
    <o>line 15</o> 
</Leg> 
<NFActy> 
    <d>line 224</d> 
    <e>line 225</e> 
    <f>line 226</f> 
    <g>line 227</g> 
</NFActy> 

Желаемая Выходной XML

<root> 
<root1>1234</root1> 
<root2>5678</root2> 
<Schedule> 
    <a>line 1</a> 
    <b>line 2</b> 
    <c>line 3</c> 
    <Rot> 
     <d>line 4</d> 
     <e>line 5</e> 
     <f>line 6</f> 
     <g>line 7</g> 
     <Duty> 
      <SequenceCount>1</SequenceCount> 
      <h>line 8</h> 
      <i>line 9</i> 
      <j>line 10</j> 
      <k>line 11</k> 
      <l>line 12</l> 
      <Leg> 
       <SequenceCount>1</SequenceCount> 
       <m>line 13</m> 
       <n>line 14</n> 
       <o>line 15</o> 
      </Leg> 
      <Leg> 
       <SequenceCount>2</SequenceCount> 
       <m>line 13</m> 
       <n>line 14</n> 
       <o>line 15</o> 
      </Leg> 
     </Duty> 
    </Rot> 
    <NFActy> 
     <SequenceCount>2</SequenceCount> 
     <d>line 214</d> 
     <e>line 215</e> 
     <f>line 216</f> 
     <g>line 217</g> 
    </NFActy> 
    <Rot> 
     <d>line 19</d> 
     <e>line 20</e> 
     <f>line 21</f> 
     <g>line 22</g> 
     <Duty> 
      <SequenceCount>3</SequenceCount> 
      <h>line 23</h> 
      <i>line 24</i> 
      <j>line 25</j> 
      <k>line 26</k> 
      <l>line 27</l> 
      <Leg> 
       <SequenceCount>1</SequenceCount> 
       <m>line 28</m> 
       <n>line 29</n> 
       <o>line 30</o> 
      </Leg> 
      <Leg> 
       <SequenceCount>2</SequenceCount> 
       <m>line 13</m> 
       <n>line 14</n> 
       <o>line 15</o> 
      /Leg> 
     </Duty> 
    </Rot> 
    <NFActy> 
     <SequenceCount>4</SequenceCount> 
     <d>line 224</d> 
     <e>line 225</e> 
     <f>line 226</f> 
     <g>line 227</g> 
    </NFActy> 
</Schedule> 

Мой XSL

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:fn="fn" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0" 
    exclude-result-prefixes="xs fn"> 

    <xsl:output indent="yes" /> 

    <xsl:template match="/"> 
     <xsl:for-each-group select="*" group-starting-with="root"> 
      <root> 
       <xsl:for-each-group select="*" group-starting-with="*[name(.)='Schedule']"> 
        <xsl:choose> 
         <xsl:when test="name(.)='Schedule'"> 
          <Schedule> 
           <xsl:apply-templates /> 
           <xsl:for-each-group select="current-group()" group-starting-with="*[name(.)='Rot']"> 
            <xsl:choose> 
             <xsl:when test="name(.)='Rot'"> 
              <Rot> 
               <xsl:apply-templates /> 
               <xsl:for-each-group select="current-group()" group-starting-with="*[name(.)='Duty']"> 
                <xsl:choose> 
                 <xsl:when test="name(.)='Duty'"> 
                  <Duty> 
                   <xsl:element name="SequenceCount"><xsl:number count="Duty|NFActy" level="any"/></xsl:element> 
                   <xsl:apply-templates /> 
                   <xsl:for-each-group select="current-group()" group-starting-with="*[name(.)='Leg']"> 
                    <xsl:choose> 
                     <xsl:when test="name(.)='Leg'"> 
                      <Leg> 
                       <xsl:element name="SequenceCount"><xsl:number value="position() - 1"/></xsl:element> 
                       <xsl:apply-templates /> 
                      </Leg> 
                     </xsl:when> 
                    </xsl:choose> 
                   </xsl:for-each-group> 
                  </Duty> 
                 </xsl:when> 
                </xsl:choose> 
               </xsl:for-each-group> 
              </Rot> 
             </xsl:when> 
            </xsl:choose> 
           </xsl:for-each-group> 
           <xsl:for-each-group select="current-group()" group-starting-with="*[name(.)='NFActy']"> 
            <xsl:choose> 
             <xsl:when test="name(.)='NFActy'"> 
              <NFActy> 
               <xsl:element name="SequenceCount"><xsl:number count="Duty|NFActy" level="any"/></xsl:element> 
               <xsl:apply-templates /> 
              </NFActy> 
             </xsl:when> 
            </xsl:choose> 
           </xsl:for-each-group> 
          </Schedule> 
         </xsl:when> 
        </xsl:choose> 
       </xsl:for-each-group> 
      </root> 
     </xsl:for-each-group> 
    </xsl:template> 

    <xsl:template match="node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()" /> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

ответ

0

Вот мое редактирование кода, вы должны убедиться, что вы обрабатываете все элементы одновременно, а не как у вас было с последовательным for-each-group.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0" 
    exclude-result-prefixes="xs"> 

    <xsl:output indent="yes" /> 

    <xsl:template match="root"> 
     <xsl:copy> 
       <xsl:for-each-group select="*" group-starting-with="Schedule"> 
        <xsl:choose> 
         <xsl:when test="self::Schedule"> 
          <Schedule> 
           <xsl:apply-templates /> 
           <xsl:for-each-group select="current-group() except ." group-starting-with="Rot | NFActy"> 
            <xsl:choose> 
             <xsl:when test="self::Rot | self::NFActy"> 
              <xsl:copy> 
               <xsl:if test="self::NFActy"> 
                <SequenceCount><xsl:number count="Duty | NFActy" level="any"/></SequenceCount> 
               </xsl:if> 
               <xsl:apply-templates /> 
               <xsl:for-each-group select="current-group() except ." group-starting-with="Duty"> 
                <xsl:choose> 
                 <xsl:when test="self::Duty"> 
                  <xsl:copy> 
                   <SequenceCount><xsl:number count="Duty | NFActy" level="any"/></SequenceCount> 
                   <xsl:apply-templates /> 
                   <xsl:for-each-group select="current-group() except ." group-starting-with="Leg"> 
                    <xsl:choose> 
                     <xsl:when test="self::Leg"> 
                      <Leg> 
                       <SequenceCount><xsl:number value="position()"/></SequenceCount> 
                       <xsl:apply-templates /> 
                      </Leg> 
                     </xsl:when> 
                    </xsl:choose> 
                   </xsl:for-each-group> 
                  </xsl:copy> 
                 </xsl:when> 
                </xsl:choose> 
               </xsl:for-each-group> 
              </xsl:copy> 
             </xsl:when> 
            </xsl:choose> 
           </xsl:for-each-group> 
          </Schedule> 
         </xsl:when> 
         <xsl:otherwise> 
          <xsl:apply-templates select="current-group()"/> 
         </xsl:otherwise> 

        </xsl:choose> 
       </xsl:for-each-group> 
       </xsl:copy> 
    </xsl:template> 

    <xsl:template match="node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="node()" /> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

Когда я применяю выше таблицы стилей с Saxon 9.5 на вход

<root> 
<root1>1234</root1> 
<root2>5678</root2> 
<Schedule> 
    <a>line 1</a> 
    <b>line 2</b> 
    <c>line 3</c> 
</Schedule> 
<Rot> 
    <d>line 4</d> 
    <e>line 5</e> 
    <f>line 6</f> 
    <g>line 7</g> 
</Rot> 
<Duty> 
    <h>line 8</h> 
    <i>line 9</i> 
    <j>line 10</j> 
    <k>line 11</k> 
    <l>line 12</l> 
</Duty> 
<Leg> 
    <m>line 13</m> 
    <n>line 14</n> 
    <o>line 15</o> 
</Leg> 
<Leg> 
    <m>line 13</m> 
    <n>line 14</n> 
    <o>line 15</o> 
</Leg> 
<NFActy> 
    <d>line 214</d> 
    <e>line 215</e> 
    <f>line 216</f> 
    <g>line 217</g> 
</NFActy> 
<Rot> 
    <d>line 19</d> 
    <e>line 20</e> 
    <f>line 21</f> 
    <g>line 22</g> 
</Rot> 
<Duty> 
    <h>line 23</h> 
    <i>line 24</i> 
    <j>line 25</j> 
    <k>line 26</k> 
    <l>line 27</l> 
</Duty> 
<Leg> 
    <m>line 28</m> 
    <n>line 29</n> 
    <o>line 30</o> 
</Leg> 
<Leg> 
    <m>line 13</m> 
    <n>line 14</n> 
    <o>line 15</o> 
</Leg> 
<NFActy> 
    <d>line 224</d> 
    <e>line 225</e> 
    <f>line 226</f> 
    <g>line 227</g> 
</NFActy> 
</root> 

я получить результат

<root> 
    <root1>1234</root1> 
    <root2>5678</root2> 
    <Schedule> 
     <a>line 1</a> 
     <b>line 2</b> 
     <c>line 3</c> 
     <Rot> 
     <d>line 4</d> 
     <e>line 5</e> 
     <f>line 6</f> 
     <g>line 7</g> 
     <Duty> 
      <SequenceCount>1</SequenceCount> 
      <h>line 8</h> 
      <i>line 9</i> 
      <j>line 10</j> 
      <k>line 11</k> 
      <l>line 12</l> 
      <Leg> 
       <SequenceCount>1</SequenceCount> 
       <m>line 13</m> 
       <n>line 14</n> 
       <o>line 15</o> 
      </Leg> 
      <Leg> 
       <SequenceCount>2</SequenceCount> 
       <m>line 13</m> 
       <n>line 14</n> 
       <o>line 15</o> 
      </Leg> 
     </Duty> 
     </Rot> 
     <NFActy> 
     <SequenceCount>2</SequenceCount> 
     <d>line 214</d> 
     <e>line 215</e> 
     <f>line 216</f> 
     <g>line 217</g> 
     </NFActy> 
     <Rot> 
     <d>line 19</d> 
     <e>line 20</e> 
     <f>line 21</f> 
     <g>line 22</g> 
     <Duty> 
      <SequenceCount>3</SequenceCount> 
      <h>line 23</h> 
      <i>line 24</i> 
      <j>line 25</j> 
      <k>line 26</k> 
      <l>line 27</l> 
      <Leg> 
       <SequenceCount>1</SequenceCount> 
       <m>line 28</m> 
       <n>line 29</n> 
       <o>line 30</o> 
      </Leg> 
      <Leg> 
       <SequenceCount>2</SequenceCount> 
       <m>line 13</m> 
       <n>line 14</n> 
       <o>line 15</o> 
      </Leg> 
     </Duty> 
     </Rot> 
     <NFActy> 
     <SequenceCount>4</SequenceCount> 
     <d>line 224</d> 
     <e>line 225</e> 
     <f>line 226</f> 
     <g>line 227</g> 
     </NFActy> 
    </Schedule> 
</root> 
+0

работает отлично. Благодарю. – user2300314