【问题标题】:XSLT - Remove duplicates, whilst adding up quantity fieldXSLT - 删除重复项,同时添加数量字段
【发布时间】:2012-08-09 20:26:04
【问题描述】:

我有一个只能使用 XSLT 解决的问题。问题是我们不希望具有相同 Id 的重复 XML 标签,但是在有多个标签的情况下,两个标签的数量字段需要加在一起。这可以很容易地在下面的 XML 中演示。

输入 XML

<root>
    <Line>
        <Id>4</Id>
        <sku>111111</sku>
        <quantity>1</quantity>
    </Line>
    <Line>
        <Id>4</Id>
        <sku>111111</sku>
        <quantity>2</quantity>
    </Line>
    <Line>
        <Id>3</Id>
        <sku>222222</sku>
        <quantity>1</quantity>
    </Line>
    <Line>
        <Id>3</Id>
        <sku>222222</sku>
        <quantity>1</quantity>
    </Line>
</root>

期望的输出

<root>
    <Line>
        <Id>4</Id>
        <sku>111111</sku>
        <quantity>3</quantity>
    </Line>
    <Line>
        <Id>3</Id>
        <sku>222222</sku>
        <quantity>2</quantity>
    </Line>
</root>

XSLT

启动 XSLT

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

    <xsl:template match="/root">
        <root>
            <xsl:apply-templates select="orderLine"/>
        </root>
    </xsl:template>

    <xsl:template match="/root/oderLine">
        <xsl:if test="not(sku = preceding-sibling::orderLine/sku)"> </xsl:if>
    </xsl:template>

</xsl:stylesheet>

比较 ID 和 SKU

例子

输入

<root>
    <Line>
        <Id>4</Id>
        <sku>111111</sku>
        <quantity>1</quantity>
    </Line>
    <Line>
        <Id>4</Id>
        <sku>111222</sku>
        <quantity>2</quantity>
    </Line>
    <Line>
        <Id>3</Id>
        <sku>222222</sku>
        <quantity>1</quantity>
    </Line>
    <Line>
        <Id>3</Id>
        <sku>222222</sku>
        <quantity>1</quantity>a
    </Line>
</root>

期望的输出

<root>
    <Line>
        <Id>4</Id>
        <sku>111111</sku>
        <quantity>1</quantity>
    </Line>
    <Line>
        <Id>4</Id>
        <sku>111222</sku>
        <quantity>2</quantity>
    </Line>
    <Line>
        <Id>3</Id>
        <sku>222222</sku>
        <quantity>2</quantity>
    </Line>
</root>

实际输出

<root>
    <Line>
        <Id>4</Id>
        <sku>111111</sku>
        <quantity>3</quantity>
    </Line>
    <Line>
        <Id>3</Id>
        <sku>222222</sku>
        <quantity>2</quantity>
    </Line>
</root>

如您所见,它只匹配 Id 而不是 SKU。

【问题讨论】:

  • 对于分组问题,您确实需要说明您使用的是 XSLT 1.0 还是 XSLT 2.0。 2.0 的解决方案总是容易得多。

标签: xml xslt duplicates


【解决方案1】:

在 XSLT 1.0 中使用 Muechian grouping:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>

<xsl:key name="l-by-id" match="Line" use="Id"/>

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

<xsl:template match="Line[generate-id() = generate-id(key('l-by-id', Id)[1])]/quantity">
  <xsl:copy>
    <xsl:value-of select="sum(key('l-by-id', ../Id)/quantity)"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="Line[generate-id() != generate-id(key('l-by-id', Id)[1])]"/>

</xsl:stylesheet>

[编辑] 这是上述解决方案对 Id 和 sku 分组的改编:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:strip-space elements="*"/>
<xsl:output indent="yes"/>

<xsl:key name="l-by-id" match="Line" use="concat(Id, '|', sku)"/>

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

<xsl:template match="Line[generate-id() = generate-id(key('l-by-id', concat(Id, '|', sku))[1])]/quantity">
  <xsl:copy>
    <xsl:value-of select="sum(key('l-by-id', concat(../Id, '|', ../sku))/quantity)"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="Line[generate-id() != generate-id(key('l-by-id', concat(Id, '|', sku))[1])]"/>

</xsl:stylesheet>

【讨论】:

  • 如果 Id 相同但 sku 不同,则在一种情况下有效。它需要对两者进行比较。我在帖子底部展示了一个示例。
  • 我将编辑并向您展示如何使用由两个元素值组成的键来解决新要求。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-03
  • 1970-01-01
  • 2020-10-13
相关资源
最近更新 更多