0

这是一个非常基本的问题,但我不明白 for-each-group 是如何工作的。我想将没有子部分的相邻顶级部分组合到一个列表中。如果有带有小节的部分,我想以不同的方式对待它们,保持顶层不变并将子部分组合成一个列表。我不想把这些混在一起。

源 XML

  <?xml version="1.0" encoding="UTF-8"?>
  <body>
     <sec>
        <title>A1</title>
        <p>Stuff A 1</p>
     </sec>
     <sec>
        <title>A2</title>
        <p>Stuff A 2</p>
     </sec>
     <sec>
        <title>A3</title>
        <p>Stuff A 3</p>
        <sec>
           <title>B1</title>
           <p>Stuff B1</p>
        </sec>
        <sec>
           <title>B2</title>
           <p>Stuff B2</p>
        </sec>
     </sec>
     <sec>
        <title>A4</title>
        <p>Stuff A 4</p>
     </sec>
  </body>

期望的结果

  <body>
     <list>
           <list-item><title>A1</title><p>Stuff A 1</p></list-item>
           <list-item><title>A2</title><p>Stuff A 2</p></list-item>
     </list>
     <sec>
        <title>A3</title>
        <p>Stuff A 3</p>
        <list>
          <list-item><title>B1</title><p>Stuff B1</p></list-item>
          <list-item><title>B2</title><p>Stuff B2</p></list-item>
        </list>
     </sec>
     <list>
        <list-item><title>A4</title><p>Stuff A 4</p></list-item>
     </list>
  </body>

XSLT 片段 这绝对是不正确的。此外,这不是我尝试过的唯一方法,只是最不混乱的发布方式。我认为for-each-group 应该工作的方式我不断收到错误An empty sequence is not allowed as the @group-adjacent attribute of xsl:for-each-group。所以这只是一个片段,让知道他们在做什么的人开始。

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

        <!-- Identity Template -->
        <xsl:template match="@*|node()" name="default" mode="#all">
            <xsl:copy>
                <xsl:copy-of select="@*"/>
                <xsl:apply-templates mode="#current"/>
            </xsl:copy>
        </xsl:template>

        <!-- Make top level body tag -->
        <xsl:template match="body">
            <body>
                <xsl:for-each-group select="sec[not(sec)]" group-adjacent=".">
                    <list>
                        <xsl:apply-templates select="current-group()"/>
                    </list>
                </xsl:for-each-group>
          </body>
        </xsl:template>

        <xsl:template match="sec[not(sec)]">
            <list-item>
                <xsl:copy-of select="*"/>
            </list-item>
        </xsl:template>

    </xsl:stylesheet>
4

1 回答 1

1

尝试

<xsl:for-each-group select="sec" group-adjacent="exists(child::sec)">

这将给出一组secsec孩子的元素,然后是一组没有孩子的元素,依此类推。

for-each-group您可能需要对这<xsl:choose><xsl:when test="child::sec">...两种组应用不同的处理。

于 2020-03-06T18:48:08.510 回答