0

我有一个如下的 XML。

<Doc>
<row>
  <Col1>13820PKS-</Col1> 
  <Col6>01</Col6> 
  <Col9>1507462800</Col9> 
  <Col12>15074628</Col12> 
  <Col14>4</Col14> 
  </row>
<row>
  <Col1>13820PKS-</Col1> 
  <Col6>01</Col6> 
  <Col9>1507462800</Col9> 
  <Col12>15074629</Col12> 
  <Col14>5</Col14> 
  </row>
 <row>
  <Col1>13820PKS-</Col1> 
  <Col6>01</Col6> 
  <Col9>1808502801</Col9> 
  <Col12>18085021</Col12> 
  <Col14>1</Col14> 
  </row>
 <row>
  <Col1>13820PKS-</Col1> 
  <Col6>02</Col6> 
  <Col9>2710004100</Col9> 
  <Col12>2710004100</Col12> 
  <Col14>1</Col14> 
  </row>
</Doc>

Document 实际上有超过 2000 行。最终结果应该是

<Doc>
    <ListID id="01">
        <MainArt>
            <ItemCode>13820PKS-</ItemCode>
            <List>
                <SubArt>
                    <ItemCode>1507462800</ItemCode>
                    <SubArtList>
                        <row>
                            <ItemCode>15074628</ItemCode>
                            <Quantity>4</Quantity>
                        </row>
                        <row>
                            <ItemCode>15074629</ItemCode>
                            <Quantity>5</Quantity>
                        </row>
                    </SubArtList>
                </SubArt>
                <SubArt>
                    <ItemCode>1808502801</ItemCode>
                    <SubArtList>
                        <row>
                            <ItemCode>18085021</ItemCode>
                            <Quantity>1</Quantity>
                        </row>
                    </SubArtList>
                </SubArt>
            </List>
        </MainArt>
    </ListID>
    <ListID id="02">
        <MainArt>
            <ItemCode>13820PKS-</ItemCode>
            <List>
                <SubArt>
                    <ItemCode>2710004100</ItemCode>
                    <SubArtList>
                        <row>
                            <ItemCode>2710004100</ItemCode>
                            <Quantity>1</Quantity>
                        </row>
                    </SubArtList>
                </SubArt>
            </List>
        </MainArt>
    </ListID>
</Doc>

我仍处于学习阶段,并不具备使用模板的技能。我尝试使用递归 for-each 循环来做到这一点,但这也没有用。任何帮助将不胜感激。谢谢

4

1 回答 1

0

拥有三个级别的多重分组并不能让您自己轻松!但是这就是你要做的......

首先,您在最顶层按Col6元素进行分组,因此您定义了一个键来按Col6值查找元素。

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

因此,对于给定值,键将返回Col6元素等于该值的所有元素。

现在,要获得“不同的” Col6值,您会查看所有元素,但只选择Col6键组中最先出现的元素。这样做是这样的,

<xsl:apply-templates 
     select="row[generate-id() = generate-id(key('Col6', Col6)[1])]" 
     mode="Col6" />

(注意这里使用模式,因为最终的 XSLT 会有多个模板匹配元素,所以需要区分它们)。

现在,在与Col6的元素匹配的模板中,您需要按Col1元素进行分组。这是它变得稍微棘手的地方,因为您需要定义一个组合Col6Col1元素的键。(允许两个Col1元素可能具有不同的Col6值)

<xsl:key name="Col1" match="row" use="concat(Col6, '|', Col1)"/>

请注意使用竖线|字符来分隔值。这可以是任何字符,只要它不在Col6Col1中出现

然后要在当前Col6中获取不同的Col1元素,您可以这样做

<xsl:apply-templates 
     select="key('Col6', Col6)
             [generate-id() = generate-id(key('Col1', concat(Col6, '|', Col1))[1])]"
     mode="Col1" />

最后,对于您的Col9元素,您将拥有一个三重连接的键。

<xsl:key name="Col9" match="row" use="concat(Col6, '|', Col1, '|', Col9)"/>

这可以以类似的方式用于获取当前Col1中的所有Col9元素。

总而言之,给出以下 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:key name="Col6" match="row" use="Col6"/>
  <xsl:key name="Col1" match="row" use="concat(Col6, '|', Col1)"/>
  <xsl:key name="Col9" match="row" use="concat(Col6, '|', Col1, '|', Col9)"/>

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

  <xsl:template match="row" mode="Col6">
    <ListID id="{Col6}">
      <xsl:apply-templates select="key('Col6', Col6)[generate-id() = generate-id(key('Col1', concat(Col6, '|', Col1))[1])]" mode="Col1" />
    </ListID>
  </xsl:template>

  <xsl:template match="row" mode="Col1">
    <MainArt>
      <ItemCode>
        <xsl:value-of select="Col1"/>
      </ItemCode>
      <List>
        <xsl:apply-templates select="key('Col1', concat(Col6, '|', Col1))[generate-id() = generate-id(key('Col9', concat(Col6, '|', Col1, '|', Col9))[1])]" mode="Col9" />
      </List>
    </MainArt>
  </xsl:template>

  <xsl:template match="row" mode="Col9">
    <SubArt>
      <ItemCode>
        <xsl:value-of select="Col9"/>
      </ItemCode>
      <SubArtList>
        <xsl:apply-templates select="key('Col9', concat(Col6, '|', Col1, '|', Col9))" mode="Col12" />
      </SubArtList>
    </SubArt>
  </xsl:template>

  <xsl:template match="row" mode="Col12">
    <row>
      <ItemCode>
        <xsl:value-of select="Col12"/>
      </ItemCode>
      <Quantity>
        <xsl:value-of select="Col14"/>
      </Quantity>
    </row>
  </xsl:template>
</xsl:stylesheet>

应用于您的示例 XML 时,将输出以下内容

<Doc>
  <ListID id="01">
    <MainArt>
      <ItemCode>13820PKS-</ItemCode>
      <List>
        <SubArt>
          <ItemCode>1507462800</ItemCode>
          <SubArtList>
            <row>
              <ItemCode>15074628</ItemCode>
              <Quantity>4</Quantity>
            </row>
            <row>
              <ItemCode>15074629</ItemCode>
              <Quantity>5</Quantity>
            </row>
          </SubArtList>
        </SubArt>
        <SubArt>
          <ItemCode>1808502801</ItemCode>
          <SubArtList>
            <row>
              <ItemCode>18085021</ItemCode>
              <Quantity>1</Quantity>
            </row>
          </SubArtList>
        </SubArt>
      </List>
    </MainArt>
  </ListID>
  <ListID id="02">
    <MainArt>
      <ItemCode>13820PKS-</ItemCode>
      <List>
        <SubArt>
          <ItemCode>2710004100</ItemCode>
          <SubArtList>
            <row>
              <ItemCode>2710004100</ItemCode>
              <Quantity>1</Quantity>
            </row>
          </SubArtList>
        </SubArt>
      </List>
    </MainArt>
  </ListID>
</Doc>
于 2013-07-16T12:44:51.720 回答