Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用XSLT的位置分组_Xslt - Fatal编程技术网

使用XSLT的位置分组

使用XSLT的位置分组,xslt,Xslt,我有包含一些文档的xml: <document> <line id="0"> <field id="0"><![CDATA[H:doc1]]></field> </line> <line id="1"> <field id="0"><![CDATA[L:1]]></field> </line>

我有包含一些文档的xml:

<document>
    <line id="0">
        <field id="0"><![CDATA[H:doc1]]></field>
    </line>
    <line id="1">
        <field id="0"><![CDATA[L:1]]></field>
    </line>
    <line id="2">
        <field id="0"><![CDATA[L:2]]></field>
    </line>
    <line id="3">
        <field id="0"><![CDATA[L:3]]></field>
    </line>
    <line id="4">
        <field id="0"><![CDATA[H:doc2]]></field>
    </line>
    <line id="5">
        <field id="0"><![CDATA[L:1]]></field>
    </line> 
</document>

H=文件标题,L=行项目。在这个例子中,whe有两个H,这意味着两个文档编号为doc1和doc2。doc1有三个行项目,doc2有一个行项目

如何使用xslt版本1转换数据以获得此结果:

<documents>
    <document>
        <header>
            <number>doc1</number>
        </header>
        <line-item>
            <line-number>1</line-number>
            <line-number>2</line-number>
            <line-number>3</line-number>
        </line-item>
    </document>
    <document>
        <header>
            <number>doc2</number>
        </header>
        <line-item>
            <line-number>1</line-number>
        </line-item>
    </document>
</documents>

文件1
1.
2.
3.
文档2
1.

此XSLT 1.0转换:

<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="line[starts-with(field,'L:')]"
   use="generate-id(preceding-sibling::line
                         [starts-with(field,'H:')]
                         [1]
                    )"/>

 <xsl:template match="/">
     <documents>
      <xsl:apply-templates/>
     </documents>
 </xsl:template>

 <xsl:template match="line[starts-with(field,'H:')]">
  <document>
   <header>
    <number><xsl:value-of select="substring-after(field,'H:')"/></number>
    <line-item>
     <xsl:apply-templates mode="inGroup" select=
        "key('kFollowing', generate-id())"/>
    </line-item>
   </header>
  </document>
 </xsl:template>

 <xsl:template match="line" mode="inGroup">
  <line-number>
   <xsl:value-of select="substring-after(field,'L:')"/>
  </line-number>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>
<document>
    <line id="0">
        <field id="0"><![CDATA[H:doc1]]></field>
    </line>
    <line id="1">
        <field id="0"><![CDATA[L:1]]></field>
    </line>
    <line id="2">
        <field id="0"><![CDATA[L:2]]></field>
    </line>
    <line id="3">
        <field id="0"><![CDATA[L:3]]></field>
    </line>
    <line id="4">
        <field id="0"><![CDATA[H:doc2]]></field>
    </line>
    <line id="5">
        <field id="0"><![CDATA[L:1]]></field>
    </line>
</document>
<documents>
   <document>
      <header>
         <number>doc1</number>
         <line-item>
            <line-number>1</line-number>
            <line-number>2</line-number>
            <line-number>3</line-number>
         </line-item>
      </header>
   </document>
   <document>
      <header>
         <number>doc2</number>
         <line-item>
            <line-number>1</line-number>
         </line-item>
      </header>
   </document>
</documents>
<document>
    <line id="0">
        <field id="0"><![CDATA[H:doc1]]></field>
    </line>
    <line id="1">
        <field id="0"><![CDATA[L:1]]></field>
    </line>
    <line id="2">
        <field id="0"><![CDATA[L:2]]></field>
    </line>
    <line id="3">
        <field id="0"><![CDATA[L:3]]></field>
    </line>
    <line id="4">
        <field id="0"><![CDATA[H:doc2]]></field>
    </line>
    <line id="5">
        <field id="0"><![CDATA[L:1]]></field>
    </line>
</document>
<documents>
   <document>
      <header>
         <number>doc1</number>
         <line-item>
            <line-number>1</line-number>
            <line-number>2</line-number>
            <line-number>3</line-number>
         </line-item>
      </header>
   </document>
   <document>
      <header>
         <number>doc2</number>
         <line-item>
            <line-number>1</line-number>
         </line-item>
      </header>
   </document>
</documents>

应用于提供的XML文档时

<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="line[starts-with(field,'L:')]"
   use="generate-id(preceding-sibling::line
                         [starts-with(field,'H:')]
                         [1]
                    )"/>

 <xsl:template match="/">
     <documents>
      <xsl:apply-templates/>
     </documents>
 </xsl:template>

 <xsl:template match="line[starts-with(field,'H:')]">
  <document>
   <header>
    <number><xsl:value-of select="substring-after(field,'H:')"/></number>
    <line-item>
     <xsl:apply-templates mode="inGroup" select=
        "key('kFollowing', generate-id())"/>
    </line-item>
   </header>
  </document>
 </xsl:template>

 <xsl:template match="line" mode="inGroup">
  <line-number>
   <xsl:value-of select="substring-after(field,'L:')"/>
  </line-number>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>
<document>
    <line id="0">
        <field id="0"><![CDATA[H:doc1]]></field>
    </line>
    <line id="1">
        <field id="0"><![CDATA[L:1]]></field>
    </line>
    <line id="2">
        <field id="0"><![CDATA[L:2]]></field>
    </line>
    <line id="3">
        <field id="0"><![CDATA[L:3]]></field>
    </line>
    <line id="4">
        <field id="0"><![CDATA[H:doc2]]></field>
    </line>
    <line id="5">
        <field id="0"><![CDATA[L:1]]></field>
    </line>
</document>
<documents>
   <document>
      <header>
         <number>doc1</number>
         <line-item>
            <line-number>1</line-number>
            <line-number>2</line-number>
            <line-number>3</line-number>
         </line-item>
      </header>
   </document>
   <document>
      <header>
         <number>doc2</number>
         <line-item>
            <line-number>1</line-number>
         </line-item>
      </header>
   </document>
</documents>
<document>
    <line id="0">
        <field id="0"><![CDATA[H:doc1]]></field>
    </line>
    <line id="1">
        <field id="0"><![CDATA[L:1]]></field>
    </line>
    <line id="2">
        <field id="0"><![CDATA[L:2]]></field>
    </line>
    <line id="3">
        <field id="0"><![CDATA[L:3]]></field>
    </line>
    <line id="4">
        <field id="0"><![CDATA[H:doc2]]></field>
    </line>
    <line id="5">
        <field id="0"><![CDATA[L:1]]></field>
    </line>
</document>
<documents>
   <document>
      <header>
         <number>doc1</number>
         <line-item>
            <line-number>1</line-number>
            <line-number>2</line-number>
            <line-number>3</line-number>
         </line-item>
      </header>
   </document>
   <document>
      <header>
         <number>doc2</number>
         <line-item>
            <line-number>1</line-number>
         </line-item>
      </header>
   </document>
</documents>

生成所需的正确结果

<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="line[starts-with(field,'L:')]"
   use="generate-id(preceding-sibling::line
                         [starts-with(field,'H:')]
                         [1]
                    )"/>

 <xsl:template match="/">
     <documents>
      <xsl:apply-templates/>
     </documents>
 </xsl:template>

 <xsl:template match="line[starts-with(field,'H:')]">
  <document>
   <header>
    <number><xsl:value-of select="substring-after(field,'H:')"/></number>
    <line-item>
     <xsl:apply-templates mode="inGroup" select=
        "key('kFollowing', generate-id())"/>
    </line-item>
   </header>
  </document>
 </xsl:template>

 <xsl:template match="line" mode="inGroup">
  <line-number>
   <xsl:value-of select="substring-after(field,'L:')"/>
  </line-number>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>
<document>
    <line id="0">
        <field id="0"><![CDATA[H:doc1]]></field>
    </line>
    <line id="1">
        <field id="0"><![CDATA[L:1]]></field>
    </line>
    <line id="2">
        <field id="0"><![CDATA[L:2]]></field>
    </line>
    <line id="3">
        <field id="0"><![CDATA[L:3]]></field>
    </line>
    <line id="4">
        <field id="0"><![CDATA[H:doc2]]></field>
    </line>
    <line id="5">
        <field id="0"><![CDATA[L:1]]></field>
    </line>
</document>
<documents>
   <document>
      <header>
         <number>doc1</number>
         <line-item>
            <line-number>1</line-number>
            <line-number>2</line-number>
            <line-number>3</line-number>
         </line-item>
      </header>
   </document>
   <document>
      <header>
         <number>doc2</number>
         <line-item>
            <line-number>1</line-number>
         </line-item>
      </header>
   </document>
</documents>
<document>
    <line id="0">
        <field id="0"><![CDATA[H:doc1]]></field>
    </line>
    <line id="1">
        <field id="0"><![CDATA[L:1]]></field>
    </line>
    <line id="2">
        <field id="0"><![CDATA[L:2]]></field>
    </line>
    <line id="3">
        <field id="0"><![CDATA[L:3]]></field>
    </line>
    <line id="4">
        <field id="0"><![CDATA[H:doc2]]></field>
    </line>
    <line id="5">
        <field id="0"><![CDATA[L:1]]></field>
    </line>
</document>
<documents>
   <document>
      <header>
         <number>doc1</number>
         <line-item>
            <line-number>1</line-number>
            <line-number>2</line-number>
            <line-number>3</line-number>
         </line-item>
      </header>
   </document>
   <document>
      <header>
         <number>doc2</number>
         <line-item>
            <line-number>1</line-number>
         </line-item>
      </header>
   </document>
</documents>

文件1
1.
2.
3.
文档2
1.

解释:使用键方便地指定和选择“标题”后面的一组完整的相邻“行”。

这里还有一个XSLT 2.0解决方案,使用


应用于提供的XML文档时

<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="line[starts-with(field,'L:')]"
   use="generate-id(preceding-sibling::line
                         [starts-with(field,'H:')]
                         [1]
                    )"/>

 <xsl:template match="/">
     <documents>
      <xsl:apply-templates/>
     </documents>
 </xsl:template>

 <xsl:template match="line[starts-with(field,'H:')]">
  <document>
   <header>
    <number><xsl:value-of select="substring-after(field,'H:')"/></number>
    <line-item>
     <xsl:apply-templates mode="inGroup" select=
        "key('kFollowing', generate-id())"/>
    </line-item>
   </header>
  </document>
 </xsl:template>

 <xsl:template match="line" mode="inGroup">
  <line-number>
   <xsl:value-of select="substring-after(field,'L:')"/>
  </line-number>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>
<document>
    <line id="0">
        <field id="0"><![CDATA[H:doc1]]></field>
    </line>
    <line id="1">
        <field id="0"><![CDATA[L:1]]></field>
    </line>
    <line id="2">
        <field id="0"><![CDATA[L:2]]></field>
    </line>
    <line id="3">
        <field id="0"><![CDATA[L:3]]></field>
    </line>
    <line id="4">
        <field id="0"><![CDATA[H:doc2]]></field>
    </line>
    <line id="5">
        <field id="0"><![CDATA[L:1]]></field>
    </line>
</document>
<documents>
   <document>
      <header>
         <number>doc1</number>
         <line-item>
            <line-number>1</line-number>
            <line-number>2</line-number>
            <line-number>3</line-number>
         </line-item>
      </header>
   </document>
   <document>
      <header>
         <number>doc2</number>
         <line-item>
            <line-number>1</line-number>
         </line-item>
      </header>
   </document>
</documents>
<document>
    <line id="0">
        <field id="0"><![CDATA[H:doc1]]></field>
    </line>
    <line id="1">
        <field id="0"><![CDATA[L:1]]></field>
    </line>
    <line id="2">
        <field id="0"><![CDATA[L:2]]></field>
    </line>
    <line id="3">
        <field id="0"><![CDATA[L:3]]></field>
    </line>
    <line id="4">
        <field id="0"><![CDATA[H:doc2]]></field>
    </line>
    <line id="5">
        <field id="0"><![CDATA[L:1]]></field>
    </line>
</document>
<documents>
   <document>
      <header>
         <number>doc1</number>
         <line-item>
            <line-number>1</line-number>
            <line-number>2</line-number>
            <line-number>3</line-number>
         </line-item>
      </header>
   </document>
   <document>
      <header>
         <number>doc2</number>
         <line-item>
            <line-number>1</line-number>
         </line-item>
      </header>
   </document>
</documents>

生成所需的正确结果

<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="line[starts-with(field,'L:')]"
   use="generate-id(preceding-sibling::line
                         [starts-with(field,'H:')]
                         [1]
                    )"/>

 <xsl:template match="/">
     <documents>
      <xsl:apply-templates/>
     </documents>
 </xsl:template>

 <xsl:template match="line[starts-with(field,'H:')]">
  <document>
   <header>
    <number><xsl:value-of select="substring-after(field,'H:')"/></number>
    <line-item>
     <xsl:apply-templates mode="inGroup" select=
        "key('kFollowing', generate-id())"/>
    </line-item>
   </header>
  </document>
 </xsl:template>

 <xsl:template match="line" mode="inGroup">
  <line-number>
   <xsl:value-of select="substring-after(field,'L:')"/>
  </line-number>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>
<document>
    <line id="0">
        <field id="0"><![CDATA[H:doc1]]></field>
    </line>
    <line id="1">
        <field id="0"><![CDATA[L:1]]></field>
    </line>
    <line id="2">
        <field id="0"><![CDATA[L:2]]></field>
    </line>
    <line id="3">
        <field id="0"><![CDATA[L:3]]></field>
    </line>
    <line id="4">
        <field id="0"><![CDATA[H:doc2]]></field>
    </line>
    <line id="5">
        <field id="0"><![CDATA[L:1]]></field>
    </line>
</document>
<documents>
   <document>
      <header>
         <number>doc1</number>
         <line-item>
            <line-number>1</line-number>
            <line-number>2</line-number>
            <line-number>3</line-number>
         </line-item>
      </header>
   </document>
   <document>
      <header>
         <number>doc2</number>
         <line-item>
            <line-number>1</line-number>
         </line-item>
      </header>
   </document>
</documents>
<document>
    <line id="0">
        <field id="0"><![CDATA[H:doc1]]></field>
    </line>
    <line id="1">
        <field id="0"><![CDATA[L:1]]></field>
    </line>
    <line id="2">
        <field id="0"><![CDATA[L:2]]></field>
    </line>
    <line id="3">
        <field id="0"><![CDATA[L:3]]></field>
    </line>
    <line id="4">
        <field id="0"><![CDATA[H:doc2]]></field>
    </line>
    <line id="5">
        <field id="0"><![CDATA[L:1]]></field>
    </line>
</document>
<documents>
   <document>
      <header>
         <number>doc1</number>
         <line-item>
            <line-number>1</line-number>
            <line-number>2</line-number>
            <line-number>3</line-number>
         </line-item>
      </header>
   </document>
   <document>
      <header>
         <number>doc2</number>
         <line-item>
            <line-number>1</line-number>
         </line-item>
      </header>
   </document>
</documents>

文件1
1.
2.
3.
文档2
1.

解释
,它的
组以
属性开头,即
当前-group()
函数。

那么-您自己尝试了什么?你哪里有麻烦?问得好,+1。请参阅我的答案,了解完整、简短且简单的XSLT 1.0解决方案(使用键):)还使用
@Petras添加了一个更短的XSLT2.0解决方案:不客气——您可能还对我的第二个答案感兴趣,该答案提供了一个更短的XSLT2.0解决方案。