XSLT 1.0在跟随某个节点时对子组进行分组

时间:2013-06-14 10:10:12

标签: xslt

输入xml:

<entry>
    <text>
        <p>xyz</p>
        <p>xyz</p>
        <p>xyz</p>
        <p>xyz</p>
        <author>abc</author>
        <p>xyz</p>
        <p>xyz</p>
        <p>xyz</p>
        <author>abc</author>
    </text>
</entry>

我正在使用XSLT 1.0。

我想在下一个<p>元素之前选择所有<author>元素,并将它们(与下一个<author>元素一起)分组到新的<div>元素下。所以期望的输出看起来像这样:

<entry>
    <text>
      <div>
        <p>xyz</p>
        <p>xyz</p>
        <p>xyz</p>
        <p>xyz</p>
        <author>abc</author>
      </div>
      <div>
        <p>xyz</p>
        <p>xyz</p>
        <p>xyz</p>
        <author>abc</author>
      </div>
    </text>
</entry>

我尝试了这个解决方案:

<xsl:template match="entry">
    <entry>
       <text>
         <div>
           <xsl:apply-templates select="child::node()[not(preceding-sibling::author)]"/>
         </div>
       </text>
    </entry>
</xsl:template>

适用于第一组<p> + <author>,但不适用于下一组。

我将不胜感激。

1 个答案:

答案 0 :(得分:0)

您可以将作者(preceding-sibling:*之前的所有元素分组为非作者(name() != 'author')并将当前作者作为下一作者的下一个作者 (generate-id( following-sibling::author[1]) = generate-id(current())):

preceding-sibling::*[ name() != 'author' and
   generate-id( following-sibling::author[1]) = generate-id(current()) ]

尝试这样的事情:

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:strip-space elements="*" />
    <xsl:output method="xml" indent="yes"/>


    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="text">
        <xsl:copy>
            <xsl:apply-templates select="author" mode="adddiv"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="author" mode="adddiv" >
        <!-- preceding siblings not  author   -->
        <xsl:variable name="fs" select="preceding-sibling::*[ name() != 'author' and
                                             generate-id( following-sibling::author[1]
                                          ) = generate-id(current()) ]" />

        <div >
            <xsl:apply-templates select="$fs | ." />
        </div>
    </xsl:template>
</xsl:stylesheet>

将生成以下输出:

<entry>
  <text>
    <div>
      <p>xyz</p>
      <p>xyz</p>
      <p>xyz</p>
      <p>xyz</p>
      <author>abc</author>
    </div>
    <div>
      <p>xyz</p>
      <p>xyz</p>
      <p>xyz</p>
      <author>abc</author>
    </div>
  </text>
</entry>