在XSL中提取连续的兄弟姐妹

时间:2011-12-17 12:04:28

标签: html xslt siblings

我有一个像这样的HTML文件:

<root>
    <br>
    <h3>The first H3 text</h3><br>
    <p>para1 content in first H3</p><br>
    <p>para2 content in first H3</p><br>
    <h3>The second H3 text</h3><br>
    <p>para1 content in second H3</p><br>
    <p>para2 content in second H3</p><br>
    <p>para3 content in second H3</p><br>
    <p>para4 content in second H3</p><br>
</root>

我想编写一个XSL,它提供如下输出:

<sec>
    <br />
    <secHead>The first H3 text</secHead><br />
    <para>para1 content in first H3</para><br />
    <para>para2 content in first H3</para><br />
</sec>
<br />
<sec>
    <br/>
    <secHead>The second H3 text</secHead><br/>
    <para>para1 content in second H3</para><br/>
    <para>para2 content in second H3</para><br/>
    <para>para3 content in second H3</para><br/>
    <para>para4 content in second H3</para><br/>
</sec>

我们怎样才能让这个输出编写XSL?

1 个答案:

答案 0 :(得分:1)

好问题,+ 1。

此转化:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kFollowing" match="*[not(self::h3)]"
  use="generate-id(preceding-sibling::h3[1])"/>

 <xsl:template match="/*">
  <xsl:apply-templates select="h3"/>
 </xsl:template>

 <xsl:template match="h3">
    <xsl:if test="position() > 1">
     <br />
    </xsl:if>
     <sec>
      <br />
      <secHead><xsl:value-of select="."/></secHead>
      <xsl:copy-of select="key('kFollowing', generate-id())"/>
     </sec>
 </xsl:template>
</xsl:stylesheet>

应用于提供的源(必须将html转换为格式良好的XML !!!):

<root>
    <br/>
    <h3>The first H3 text</h3><br/>
    <p>para1 content in first H3</p><br/>
    <p>para2 content in first H3</p><br/>
    <h3>The second H3 text</h3><br/>
    <p>para1 content in second H3</p><br/>
    <p>para2 content in second H3</p><br/>
    <p>para3 content in second H3</p><br/>
    <p>para4 content in second H3</p><br/>
</root>

生成想要的正确结果

<sec>
   <br/>
   <secHead>The first H3 text</secHead>
   <br/>
   <p>para1 content in first H3</p>
   <br/>
   <p>para2 content in first H3</p>
   <br/>
</sec>
<br/>
<sec>
   <br/>
   <secHead>The second H3 text</secHead>
   <br/>
   <p>para1 content in second H3</p>
   <br/>
   <p>para2 content in second H3</p>
   <br/>
   <p>para3 content in second H3</p>
   <br/>
   <p>para4 content in second H3</p>
   <br/>
</sec>

<强>解释

此解决方案的关键点是我们定义了一个xsl:key,它捕获h3元素及其所有紧随其后的兄弟元素之间的关系(这样它们不是h3他们自己和h3是他们的第一个h3兄弟姐妹。)