在 XSL 中提取连续兄弟姐妹

发布于 2024-12-21 22:19:29 字数 1276 浏览 4 评论 0原文

我有一个像这样的 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 获得此输出?

I have an HTML file like this:

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

I want to write an XSL which gives output like this one:

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

How can we get this output writing XSL?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你的往事 2024-12-28 22:19:29

好问题,+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 前面的兄弟)。

Good question, +1.

This transformation:

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

when applied on the provided source (the html must be converted to wellformed 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>

produces the wanted, correct result:

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

Explanation:

The key point in this solution is that we define an xsl:key that captures the relation between an h3 element and all its immediate following siblings elements (such that they aren't h3 themselves and this h3 is their first h3 preceding sibling).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文