【问题标题】:XSL Grouping with 1.0使用 1.0 进行 XSL 分组
【发布时间】:2013-07-16 08:30:51
【问题描述】:

我有一个如下的 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>

文档实际上有超过 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 循环来做到这一点,但这也没有用。 任何帮助将不胜感激。谢谢

【问题讨论】:

  • 您是否要按 Col6 对行进行分组?
  • 在 XSLT 1.0 中,您需要使用一种称为 Muenchian Grouping (jenitennison.com/xslt/grouping/muenchian.html) 的技术,这可能会让您在第一次看到它时感到头疼,但这是最好的方法!您能否修改您的问题以显示给定输入的实际预期输出,因为看起来您可能需要在此处进行多个分组。谢谢!
  • 感谢您的回复。我知道 Muenchian 分组方法(知道意味着我读过它),但正如你所说,它让我的大脑受伤:)。
  • 我还在学习如何实现模板,我认为如果不了解模板实现,我将无法理解“Muenchian Grouping”。我必须做多个分组。 Col12 和 Col14 在 Col9 之下,在 Col1 之下,在 Col6 之下。我知道它有点复杂。第二部分是预期的输出。
  • 第二部分显示了预期输出的结构,但不是您真正期望的实际输出,我相信?因此,如果您可以显示当前输入的实际输出,那将有很大帮助。谢谢!

标签: xslt xpath key grouping


【解决方案1】:

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

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

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

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

现在,要获得'distinct' Col6 值,您会查看所有 row 元素,但只选择最先出现的元素Col6 键的组。这样做是这样的,

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

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

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

<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>

【讨论】:

  • 谢谢。它按我的意愿工作,感谢您的详细解释。我真的很感激。
猜你喜欢
  • 1970-01-01
  • 2013-02-26
  • 1970-01-01
  • 1970-01-01
  • 2016-01-25
  • 1970-01-01
  • 2015-07-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多