XSLT - 与给定节点的以下兄弟姐妹一起工作

XSLT - working with following siblings of given node

我有一个 xml 如下,

<doc>
    <h1>header 1</h1>
    <p>para 1</p>
    <p>para 2</p>

    <h1>header 2</h1>
    <p>para 3</p>
    <p>para 4</p>

    <h1>header 3</h1>
    <p>para 5</p>
    <p>para 6</p>
</doc>

我的要求是从 <h1> 和 link 这些列表项创建无序列表,并且它在 <p> 个节点之后。

所以期望的输出应该是,

<doc>
    <div name="list">
        <ul>
            <li><a href="h1-1">header 1</a></li>
            <li><a href="h1-2">header 2</a></li>
            <li><a href="h1-3">header 3</a></li>
        </ul>
    </div>
    <div class="content">
        <div id="h1-1">
            <p>para 1</p>
            <p>para 2</p>
        </div>
        <div id="h1-2">
            <p>para 3</p>
            <p>para 4</p>
        </div>
        <div id="h1-3">
            <p>para 5</p>
            <p>para 6</p>
        </div>
    </div>
</doc>

我已经编写了以下 xsl 来完成此任务,

       <doc>
            <div name="list">
                <ul>
                <xsl:for-each-group select="*" group-starting-with="h1">                    
                    <li><a href="h1-{count(preceding::h1)+1}"><xsl:apply-templates/></a></li>                   
                </xsl:for-each-group>
                </ul>
            </div>

            <div class="content">
                <xsl:for-each select="h1">
                    <div id="h1-{count(preceding::h1)+1}">
                        <!-- should copy follwing <p> nodes in <h1> -->
                    </div>
                </xsl:for-each>
            </div>
        </doc>

我无法解决的是如何将 <p> 节点作为以下兄弟节点放置到 <h1> 但在出现另一个 <h1> 之前。 (例子会给出清晰的思路。)

任何人都可以建议我解决这个问题吗?

您可能只想查看您的来源 xml。如果段落只是该特定章节的一部分,它们可能应该是 header 的 child 节点。现在没有真正的方法来识别正确的段落。

完成后,解决方案应该更简单。

您的方法需要反转:第一个 div 不需要分组,第二个需要。

而且不需要考虑后面(或前面)的兄弟姐妹;只需将组缩小到 p 个元素即可。

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="UTF-8" indent="yes"/>

<xsl:template match="doc">
    <doc>
        <div name="list">
            <ul>
                <xsl:for-each select="h1">
                    <li>
                        <a href="h1-{position()}">
                            <xsl:value-of select="."/>
                        </a>
                    </li>
                </xsl:for-each>
            </ul>
        </div>
        <div class="content">
            <xsl:for-each-group select="*" group-starting-with="h1">  
                <div id="h1-{position()}">
                    <xsl:copy-of select="current-group()[self::p]"/>
                </div>
            </xsl:for-each-group>                
        </div>
    </doc>
</xsl:template>

</xsl:stylesheet>