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对XML进行分组_Xslt - Fatal编程技术网

基于标题或文档条目使用xslt对XML进行分组

基于标题或文档条目使用xslt对XML进行分组,xslt,Xslt,对于下面的XML代码,如何使用xlst对XML进行分组。 以下是输入XML:我使用这个输入XML来导入ERP系统 <row> <Ref>1</Ref> <Code>IT001</Code> <Qty>11</Qty> </row> <row> <Ref>1</Ref>

对于下面的XML代码,如何使用xlst对XML进行分组。 以下是输入XML:我使用这个输入XML来导入ERP系统

 <row>
        <Ref>1</Ref>
        <Code>IT001</Code>
        <Qty>11</Qty>
    </row>
    <row>
        <Ref>1</Ref>
        <Code>IT002</Code>
        <Qty>21</Qty>
    </row>
    <row>
        <Ref>2</Ref>
        <Code>IT002</Code>
        <Qty>12</Qty>
    </row>
以下是输出或预期的XML:ERP系统通常接受每个文档的一行及其文档行的同级。因此,需要以下所需输出

<Document>
    <Ref>1</Ref><Lines>
        <Item>
            <Code>IT001</Code>
            <Qty>11</Qty>
        </Item>
        <Item>
            <Code>IT002</Code>
            <Qty>21</Qty>
        </Item>
    </Lines>
</Document>
<Document>
    <OrderRef>2</OrderRef>
    <Lines>
        <Item>
            <Code>IT002</Code>
            <Qty>12</Qty>
        </Item>
    </Lines>
</Document>

让我们从更正源XML开始:

必须只有一个根元素(我称之为根) 其中可以有多个(如文档)元素

执行转换的模板应与 根元素

正如我从预期输出中看到的,您希望对文档进行分组 元素,因此在下面的脚本中 每个组指令对应的xsl:

对于每个这样的组,都应该有文档输出元素 在它的内部有一个Ref元素和当前值 分组键

然后应该有一个Lines元素,在其中,每个 当前组的成员,应该有Item元素 在它里面有两个子元素,它们的值是 源元素

因此,整个脚本可以如下所示:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
  <xsl:strip-space elements="*"/>

  <xsl:template match="Root">
    <xsl:copy>
      <xsl:for-each-group select="Document" group-by="DocumentRef">
        <Document>
          <Ref><xsl:value-of select="current-grouping-key()"/></Ref>
          <Lines>
            <xsl:for-each select="current-group()">
              <Item>
                <ItemCode><xsl:value-of select="DocumentLines/ItemCode"/></ItemCode>
                <Qty><xsl:value-of select="DocumentLines/ItemQty"/></Qty>
              </Item>
            </xsl:for-each>
          </Lines>
        </Document>      
      </xsl:for-each-group>
    </xsl:copy>
  </xsl:template>
</xsl:transform>
它在上“调用操作”(在本例中为
xsl:apply templates
) 每组中的第一个对象

我的初始解决方案中的其余代码已移至 与行匹配的模板

它的初始部分为当前组执行操作 (生成输出文档、参考、卡片代码和行) 元素)

其余的(
xsl:for each
)为单个 当前组的成员、生成项、项代码 和数量元素

我在xsltransform中更新了您的解决方案,因此您可以查看 穿上

注意,我将XSLT引擎更改为Saxon 6.5.5。你也可以 将其切换到Xalan,尽管这样会使缩进变松

如果这种方法对你来说是新的,也许你应该读一些关于 生成id和Muenchian分组本身。即使StackOverflow也包含
关于这些问题的帖子很多。

请发布您的XSL,即使它不起作用。请参阅。请在问题本身中发布所有代码(XML、XSLT、预期输出)。您好@Valdi_-Bo,我的应用程序不支持XSL版本2.0,因此不支持每个组的XSL:。有没有办法用XSL 1.0版本实现同样的功能?Hi@Valdi_Bo修改了工作副本以匹配我的精确输入xml。顺便说一下,我使用了您的xslt语句,它工作得很好。但我的应用程序不支持xsl 2.0版,因此不支持每个组的xsl:for。XSL工作副本在这里。
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
  <xsl:strip-space elements="*"/>

  <xsl:key name="groups" match="row" use="OrderRef"/>

  <xsl:template match="Payload">
    <xsl:copy>
      <xsl:apply-templates select="row[generate-id() = generate-id(
        key('groups', OrderRef)[1])]"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="row">
    <Document>
      <Ref><xsl:value-of select="OrderRef"/></Ref>
      <CardCode><xsl:value-of select="CustomerCode"/></CardCode>
      <Lines>
        <xsl:for-each select="key('groups', OrderRef)">
          <Item>
            <ItemCode><xsl:value-of select="ItemCode"/></ItemCode>
            <Qty><xsl:value-of select="Quantity"/></Qty>
          </Item>  
        </xsl:for-each>
      </Lines>
    </Document>
  </xsl:template>
</xsl:transform>
<xsl:apply-templates select="row[generate-id() = generate-id(
  key('groups', OrderRef)[1])]"/>