当前位置: 动力学知识库 > 问答 > 编程问答 >

xml - XSLT - working with following siblings of given node

问题描述:

I've a xml like follows,

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

My requirement is create unordered list from <h1> and link those list items with it's following <p> nodes.

so the desired output should be,

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

I've written following xsl to achieve this task,

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

what I unable to solve is how can I copy <p> nodes which are placed as following siblings to <h1> but before appear another <h1>. (example would give clear idea.)

can anyone suggest me a solution to that?

网友答案:

Your approach needs to reversed: the first div needs no grouping, the second one does.

And there is no need to consider following (or preceding) siblings; just narrow down the group to p elements only.

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>
网友答案:

You might simply want to look at your source xml. If the paragraphs are only part of that specific chapter they should probably be child nodes of the header. There is no real way to identify the correct paragraphs right now.

Once you have done so the solution should be way simpler.

分享给朋友:
您可能感兴趣的文章:
随机阅读: