繁体   English   中英

XSLT 2.0分组<xsl:for-each-group>

[英]XSLT 2.0 grouping with <xsl:for-each-group>

我正在尝试使用xsl:for-each在XSLT 2.0中对元素进行分组。

以下是我输入的说明:

<root>
     <chapter>
           <heading> heading text </heading>
           <title> title </title>
           <p> 1111 </p>
           <p> 2222 </p>
           <center> text </center>
           <p> 3333 </p>
           <title>  another title </title>
           <p> 4444 </p>
           <center> text </center>
           <p> 5555 </p>
     </chapter>
     <chapter>
          <heading> heading text </heading>
          <title>  another title </title>
          <p> 6666 </p>
          <p> 7777 </p>
          <title>  another title </title>
          <p> 8888 </p>
          <p> 9999 </p>
     </chapter>
<root>

我试图通过匹配每个<title>元素并将每个后续元素分组直到下一个<title>成为元素<section>来对该文档进行分组。 这是我希望我的输出看起来像:

<root>
     <chapter>
          <heading> Heading text </heading>
          <section>
               <title>  title </title>
               <p> 1111 </p>
               <p> 2222 </p>
               <center> text </center>
               <p> 3333 </p>
          </section>
          <section>
               <title>  title </title>
               <p> 4444 </p>
               <center> text </center>
               <p> 5555 </p>
          </section>
          <section>
               <title>  title </title>
               <p> 6666 </p>
               <p> 7777 </p>
               <center> text </center>
               <p> 8888 </p>
               <p> 9999 </p>
          </section>
     <chapter>
<root>

我当前的模板不起作用:

<xsl:template match="chapter">
    <chapter>
      <xsl:for-each-group select="*" group-starting-with="title">
             <section>
                <xsl:copy-of select="current-group()" />
             </section>
      </xsl:for-each-group>
    </chapter>             
</xsl:template>

上面的样式表确实对我想要的部分进行分组,但是由于某种原因,它还将每个<heading>元素分组到它自己的<section>中。 有什么建议么?

提前致谢。

我会用......

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

<xsl:template match="/*">
  <root>
    <xsl:for-each-group select="chapter" group-by="heading">
      <chapter>
        <xsl:copy-of select="current-group()[1]/heading" />
        <xsl:for-each-group select="current-group()/(* except heading)"
                            group-starting-with="title">
          <section>
            <xsl:copy-of select="current-group()" />
          </section>
        </xsl:for-each-group>
      </chapter>
    </xsl:for-each-group>
  </root>
</xsl:template>

</xsl:stylesheet>

我通常使用xsl:在for-each-group的主体中选择,以区分真正用group-starting-with元素开始的组,从第一个“真实组”之前的“leading rump”开始。 如果你知道“领先的臀部”只包含一个标题元素,那么你已经获得了许多其他解决方案。 另一个更通用的解决方案(因为它不会对臀部中的内容做出任何假设),但沿着相同的路线,是:

<xsl:copy-of select="title[1]/preceding-sibling::*">
<xsl:for-each-group select="title[1]/(., following-sibling::*)">
  <section>
     <xsl:copy-of select="current-group()"/>
  </section>
</xsl:for-each-group>

你可能想要

<xsl:copy-of select="current-group()" />

而不是value-of 对于标题,如果您知道每章只有一个heading元素,那么您可以说

<xsl:template match="chapter">
      <xsl:copy-of select="heading" />
      <xsl:for-each-group select="*[not(self::heading)]" group-starting-with="title">
             <section>
                <xsl:copy-of select="current-group()" />
             </section>
      </xsl:for-each-group>             
</xsl:template>

即分别拉出标题,然后将其从要分组的元素集中排除。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM