【问题标题】:XSLT - working with following siblings of given nodeXSLT - 使用给定节点的以下兄弟姐妹
【发布时间】:2015-09-14 10:02:13
【问题描述】:

我有一个如下的 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>

我的要求是从&lt;h1&gt; 创建无序列表,并将这些列表项与其下面的&lt;p&gt; 节点链接。

所以期望的输出应该是,

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

我无法解决的是如何将&lt;p&gt; 节点复制到&lt;h1&gt;,但在出现另一个&lt;h1&gt; 之前。 (示例会给出清晰的想法。)

谁能建议我解决这个问题?

【问题讨论】:

    标签: xml xslt xslt-2.0


    【解决方案1】:

    您的方法需要颠倒:第一个 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>
    

    【讨论】:

      【解决方案2】:

      您可能只是想查看您的源 xml。如果段落只是该特定章节的一部分,它们可能应该是标题的子节点。目前还没有真正的方法来识别正确的段落。

      一旦你这样做了,解决方案应该会更简单。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-12-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多