使用xsl:for-each-group

时间:2012-07-27 18:16:46

标签: xslt xpath xslt-2.0

这是我的要求。我的示例输入文档如下所示。 (我添加了白线以表明清楚)

<body>
       <p name="h-title" other="main">Introduction</p>
       <p name="h-titledesc " other="other-desc">XSLT and XQuery</p>


       <p name=""> XSLT is used to write stylesheets.</p>
    <p name="section-title" other=" other-section">XSLT</p>
    <p name="section-desc" other=" other-sectionsdesc">XSLT</p>
    <p name=""> Some text.</p>
    <p name="">
          <p1 name="bold"> XQuery is used to query XML databases.</p1>
       </p>
    <p name="h1-title" other=" other-h1">XSLT</p>
    <p name=""> Some text.</p>
       <p name="h2-title " name="other-h2">XQuery</p>
       <p name="">
          <p1 name="bold"> XQuery is used to query XML databases.</p1>
       </p>
       <p name="h3-title" name="other-h3">XQuery and stylesheets</p>
       <p name="">
          <p1 name="bold"> XQuery is used to query XML databases.</p1>
       </p>


    <p name="section-title" other=" other-section">XSLT</p>
    <p name="section-desc" other=" other-sectionsdesc">XSLT</p>
    <p name=""> Some text.</p>
    <p name="">
          <p1 name="bold"> XQuery is used to query XML databases.</p1>
       </p>
    <p name="h1-title" other=" other-h1">XSLT</p>
    <p name=""> Some text.</p>
       <p name="h2-title " name="other-h2">XQuery</p>
       <p name="">
          <p1 name="bold"> XQuery is used to query XML databases.</p1>
       </p>
       <p name="h3-title" name="other-h3">XQuery and stylesheets</p>
       <p name="">
          <p1 name="bold"> XQuery is used to query XML databases.</p1>
       </p>


       <p name ="summary-title">this is summary</p>
       <p name="summary-desc " other="other-summarydesc">the summary</p>
    </body>

现在我想要的输出就是这个。

<body>
       <p name="h-title" other="main">Introduction</p>
       <p name="h-titledesc " other="other-desc">XSLT and XQuery</p>


       <p name=""> XSLT is used to write stylesheets.</p>

    <body-contents>
        <p name="section-title" other=" other-section">XSLT</p>
        <p name="section-desc" other=" other-sectionsdesc">XSLT</p>
        <p name=""> Some text.</p>
        <p name="">
              <p1 name="bold"> XQuery is used to query XML databases.</p1>
           </p>
        <h1>
        <p name="h1-title" other=" other-h1">XSLT</p>
        <p name=""> Some text.</p>
        <h2>
           <p name="h2-title " name="other-h2">XQuery</p>
           <p name="">
              <p1 name="bold"> XQuery is used to query XML databases.</p1>
           </p>
        <h3>
           <p name="h3-title" name="other-h3">XQuery and stylesheets</p>
           <p name="">
              <p1 name="bold"> XQuery is used to query XML databases.</p1>
           </p>
        </h3>
    </h2>
    </h1>
    </body-contents>
    <body-contents>
        <p name="section-title" other=" other-section">XSLT</p>
        <p name="section-desc" other=" other-sectionsdesc">XSLT</p>
        <p name=""> Some text.</p>
        <p name="">
              <p1 name="bold"> XQuery is used to query XML databases.</p1>
           </p>
        <h1>
        <p name="h1-title" other=" other-h1">XSLT</p>
        <p name=""> Some text.</p>
        <h2>
           <p name="h2-title " name="other-h2">XQuery</p>
           <p name="">
              <p1 name="bold"> XQuery is used to query XML databases.</p1>
           </p>
        <h3>
           <p name="h3-title" name="other-h3">XQuery and stylesheets</p>
           <p name="">
              <p1 name="bold"> XQuery is used to query XML databases.</p1>
           </p>
        </h3>
    </h2>
    </h1>

    </body-contents>
    <body-contents>
           <p name ="summary-title">this is summary</p>
           <p name="summary-desc " other="other-summarydesc">the summary</p>
    </body-contents>
    </body>

请帮我解决这个问题。

{的可选的 有一些限制:

  • h1,h2,h3依次来(这意味着,h3不介于h1和h2之间)
  • 名称=&#34的行; section-title&#34;应该在name =&#34; section-desc&#34;
  • 之前
  • h1,h2,h3等应该在section-desc之后。

我解决了h1,h2,h3等here的问题。我知道这很有用。任何帮助都很棒。

如果违反这些规则,则不应发生转变。 }

1 个答案:

答案 0 :(得分:3)

这是我对先前发布的样式表的调整,它在调用递归函数分组级别之前只执行了额外的group-starting-with。我意识到这与你之前发表的帖子中的建议相同,但到目前为止,我不清楚为什么这个建议不适合你。

所以这是样式表:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:mf="http://example.com/mf"
  exclude-result-prefixes="xs mf">

<xsl:param name="prefix" as="xs:string" select="'h'"/>
<xsl:param name="suffix" as="xs:string" select="'-title'"/>

<xsl:output method="xml" version="1.0" indent="yes"/>

<xsl:function name="mf:group" as="node()*">
  <xsl:param name="items" as="node()*"/>
  <xsl:param name="level" as="xs:integer"/>
  <xsl:for-each-group select="$items" group-starting-with="p[@name = concat($prefix, $level, $suffix)]">
    <xsl:choose>
      <xsl:when test="not(self::p[@name = concat($prefix, $level, $suffix)])">
        <xsl:apply-templates select="current-group()"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:element name="h{$level}">
          <xsl:apply-templates select="."/>
          <xsl:sequence select="mf:group(current-group() except ., $level + 1)"/>
        </xsl:element>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:for-each-group>
</xsl:function>

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

<xsl:template match="body">
  <xsl:copy>
    <xsl:for-each-group select="*" group-starting-with="p[@name = 'section-title' or @name = 'summary-title']">
      <xsl:choose>
        <xsl:when test="not(self::p[@name = 'section-title' or @name = 'summary-title'])">
          <xsl:apply-templates select="current-group()"/>
        </xsl:when>
        <xsl:otherwise>
          <body-contents>
             <xsl:sequence select="mf:group(current-group(), 1)"/>
          </body-contents>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:for-each-group>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

当我将带有Saxon 9.4的样式表应用于更正的输入

<body>
       <p name="h-title" other="main">Introduction</p>
       <p name="h-titledesc " other="other-desc">XSLT and XQuery</p>


       <p name=""> XSLT is used to write stylesheets.</p>
    <p name="section-title" other=" other-section">XSLT</p>
    <p name="section-desc" other=" other-sectionsdesc">XSLT</p>
    <p name=""> Some text.</p>
    <p name="">
          <p1 name="bold"> XQuery is used to query XML databases.</p1>
       </p>
    <p name="h1-title" other=" other-h1">XSLT</p>
    <p name=""> Some text.</p>
       <p name="h2-title" other="other-h2">XQuery</p>
       <p name="">
          <p1 name="bold"> XQuery is used to query XML databases.</p1>
       </p>
       <p name="h3-title" other="other-h3">XQuery and stylesheets</p>
       <p name="">
          <p1 name="bold"> XQuery is used to query XML databases.</p1>
       </p>


    <p name="section-title" other=" other-section">XSLT</p>
    <p name="section-desc" other=" other-sectionsdesc">XSLT</p>
    <p name=""> Some text.</p>
    <p name="">
          <p1 name="bold"> XQuery is used to query XML databases.</p1>
       </p>
    <p name="h1-title" other=" other-h1">XSLT</p>
    <p name=""> Some text.</p>
       <p name="h2-title" other="other-h2">XQuery</p>
       <p name="">
          <p1 name="bold"> XQuery is used to query XML databases.</p1>
       </p>
       <p name="h3-title" other="other-h3">XQuery and stylesheets</p>
       <p name="">
          <p1 name="bold"> XQuery is used to query XML databases.</p1>
       </p>


       <p name ="summary-title">this is summary</p>
       <p name="summary-desc " other="other-summarydesc">the summary</p>
    </body>

我得到了输出

<body>
   <p name="h-title" other="main">Introduction</p>
   <p name="h-titledesc " other="other-desc">XSLT and XQuery</p>
   <p name=""> XSLT is used to write stylesheets.</p>
   <body-contents>
      <p name="section-title" other=" other-section">XSLT</p>
      <p name="section-desc" other=" other-sectionsdesc">XSLT</p>
      <p name=""> Some text.</p>
      <p name="">
          <p1 name="bold"> XQuery is used to query XML databases.</p1>
       </p>
      <h1>
         <p name="h1-title" other=" other-h1">XSLT</p>
         <p name=""> Some text.</p>
         <h2>
            <p name="h2-title" other="other-h2">XQuery</p>
            <p name="">
               <p1 name="bold"> XQuery is used to query XML databases.</p1>
            </p>
            <h3>
               <p name="h3-title" other="other-h3">XQuery and stylesheets</p>
               <p name="">
                  <p1 name="bold"> XQuery is used to query XML databases.</p1>
               </p>
            </h3>
         </h2>
      </h1>
   </body-contents>
   <body-contents>
      <p name="section-title" other=" other-section">XSLT</p>
      <p name="section-desc" other=" other-sectionsdesc">XSLT</p>
      <p name=""> Some text.</p>
      <p name="">
          <p1 name="bold"> XQuery is used to query XML databases.</p1>
       </p>
      <h1>
         <p name="h1-title" other=" other-h1">XSLT</p>
         <p name=""> Some text.</p>
         <h2>
            <p name="h2-title" other="other-h2">XQuery</p>
            <p name="">
               <p1 name="bold"> XQuery is used to query XML databases.</p1>
            </p>
            <h3>
               <p name="h3-title" other="other-h3">XQuery and stylesheets</p>
               <p name="">
                  <p1 name="bold"> XQuery is used to query XML databases.</p1>
               </p>
            </h3>
         </h2>
      </h1>
   </body-contents>
   <body-contents>
      <p name="summary-title">this is summary</p>
      <p name="summary-desc " other="other-summarydesc">the summary</p>
   </body-contents>
</body>

请在下次提供输入样本时确保其格式正确,到目前为止,您始终发布<p name="h2-title " name="other-h2">XQuery</p>之类的内容,并且无法使用同名的两个属性。