xsl:for-each-group 位置分组平面 xml 到分层 [英] xsl:for-each-group positional grouping flat xml to hierarchical

查看:20
本文介绍了xsl:for-each-group 位置分组平面 xml 到分层的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个平面 xml 文件需要转换为层次结构.我使用了这里 xsl:for-each-group help needed 中的嵌套分组想法.除了几个问题外,它在大多数情况下都有效:

I have a flat xml file that needs to be converted to hierarchical. I used the nested grouping idea from here xsl:for-each-group help needed. It's working for the most part except for a couple of issues:

1) 元素 root1 和 root2 没有出现.

1) The elements root1 and root2 are not showing up.

2) NFActy 元素的位置不正确.第一个 NFActy 应该在 2 个 Rot 元素之间.

2) The location of element NFActy is incorrect. The first NFActy should be between the 2 Rot elements.

3) 责任与义务NFActy 元素被视为一组用于计算 SequenceCount.

3) The Duty & NFActy elements are treated as one group for calculating the SequenceCount.

4) 对于 Leg 元素,一个职责内的每组 Leg 元素都应分组,以便为​​ leg 元素进行 SequenceCount.

4) For Leg elements each set of Leg elements within one duty should be grouped for SequenceCount for leg elements.

非常感谢任何帮助.

谢谢.

输入 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>

推荐答案

这是我对您代码的编辑,您需要确保同时处理所有元素,而不是像顺序 for-每组.

Here is my edit of your code, you need to make sure you process all elements at the same time and not as you had with sequential 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 的样式表应用于输入时

When I apply above stylesheet with Saxon 9.5 to the input

<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>

这篇关于xsl:for-each-group 位置分组平面 xml 到分层的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆