1

我的 XML 如下所示:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<BATCHES>
    <item>
        <Material>1000000079</Material>
        <Description>330 Bulk</Description>
        <Tank>T123</Tank>
        <Batch>2013225287</Batch>
        <Quantity>510</Quantity>
    </item>
    <item>
        <Material>1000000079</Material>
        <Description>330 Bulk</Description>
        <Tank>T123</Tank>
        <Batch>2013225301</Batch>
        <Quantity>520</Quantity>
    </item>
    <item>
        <Material>1000000196</Material>
        <Description>340R Bulk</Description>
        <Tank>T700</Tank>
        <Batch>1000188378</Batch>
        <Quantity>510</Quantity>
    </item>
    <item>
        <Material>1000002754</Material>
        <Description>43 Bulk</Description>
        <Tank>T515</Tank>
        <Batch>2013180125</Batch>
        <Quantity>300</Quantity>
    </item>
    <item>
        <Material>1000002754</Material>
        <Description>43 Bulk</Description>
        <Tank>T515</Tank>
        <Batch>2013203124</Batch>
        <Quantity>200</Quantity>
    </item>
    <item>
        <Material>1000002754</Material>
        <Description>43 Bulk</Description>
        <Tank>T515</Tank>
        <Batch>2013214839</Batch>
        <Quantity>700</Quantity>
    </item>
    <item>
        <Material>1000002754</Material>
        <Description>43 Bulk</Description>
        <Tank>T517</Tank>
        <Batch>2013214342</Batch>
        <Quantity>890</Quantity>
    </item>
</BATCHES>

我原来的 XSLT 是这样的:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output encoding="UTF-8" indent="yes" method="xml" version="1.0"/>
    <xsl:template match="/">
        <Rowsets>
            <Rowset>
                <xsl:variable name="materials" select=".//item[Tank!='RECV' and Tank!='PARK'] "/>
                <xsl:for-each select="$materials">
                    <xsl:if test="generate-id(.)=                       generate-id($materials[Material=current()/Material])">
                        <Row>
                            <Material>
                                <xsl:value-of select="Material"/>
                            </Material>
                            <Description>
                                <xsl:value-of select="Description"/>
                            </Description>
                            <Value>
                                <xsl:for-each select="$materials[Material=current()/Material]/Tank">
                                    <xsl:if test="node()">
                                        <xsl:value-of select="concat(.,'||')"/>
                                    </xsl:if>
                                </xsl:for-each>
                            </Value>
                        </Row>
                    </xsl:if>
                </xsl:for-each>
            </Rowset>
        </Rowsets>
    </xsl:template>
</xsl:stylesheet>

此 XSLT 的结果如下所示:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Rowsets>
<Rowset>
<Row>
<Material>1000000079</Material>
<Description>330 Bulk</Description>
<Value>T123||T123||</Value>
</Row>
<Row>
<Material>1000000196</Material>
<Description>340R Bulk</Description>
<Value>T700||</Value>
</Row>
<Row>
<Material>1000002754</Material>
<Description>43 Bulk</Description>
<Value>T515||T517||</Value>
</Row>
</Rowset>
</Rowsets>

我想删除重复的坦克,同时在值字段中连接它。所以我将我的 XSLT 更改为以下内容:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output encoding="UTF-8" indent="yes" method="xml" version="1.0"/>
    <xsl:template match="/">
        <Rowsets>
            <Rowset>
                <xsl:variable name="materials" select=".//item[Tank!='RECV' and Tank!='PARK' and Quantity &gt; 500]"/>
                <xsl:for-each select="$materials">
                    <xsl:if test="generate-id(.)= generate-id($materials[Material=current()/Material])">
                        <Row>
                            <Material>
                                <xsl:value-of select="Material"/>
                            </Material>
                            <Description>
                                <xsl:value-of select="Description"/>
                            </Description>
                            <Value>
                                <xsl:for-each select="$materials[Material=current()/Material]/Tank[not(.=preceding::Tank)]">
                                    <xsl:if test="node()">
                                        <xsl:value-of select="concat(.,'||')"/>
                                    </xsl:if>
                                </xsl:for-each>
                            </Value>
                        </Row>
                    </xsl:if>
                </xsl:for-each>
            </Rowset>
        </Rowsets>
    </xsl:template>
</xsl:stylesheet>

我的结果现在看起来像这样:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Rowsets>
<Rowset>
<Row>
<Material>1000000079</Material>
<Description>330 Bulk</Description>
<Value>T123||</Value>
</Row>
<Row>
<Material>1000000196</Material>
<Description>340R Bulk</Description>
<Value>T700||</Value>
</Row>
<Row>
<Material>1000002754</Material>
<Description>43 Bulk</Description>
<Value>T517||</Value>
</Row>
</Rowset>
</Rowsets>

它删除了物料 1000000079 的重复罐 T123,但对于物料 1000002754,它甚至删除了应该出现在值字段中的 T515,因为它的数量大于 500,如下所示:

<item>
            <Material>1000002754</Material>
            <Description>43 Bulk</Description>
            <Tank>T515</Tank>
            <Batch>2013214839</Batch>
            <Quantity>700</Quantity>
        </item>

我在这里做错了什么?

4

1 回答 1

2

好的,我看到了你的问题。

为此,基于密钥的解决方案使用密钥分组:Muenchian 方法:试试这个:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output encoding="UTF-8" indent="yes" method="xml" version="1.0"/>
    <xsl:key name="kMaterial" match="item[Tank!='RECV' and Tank!='PARK' and Quantity &gt; 500]" 
             use="Material"/>
    <xsl:key name="kMaterialTank" match="item[Tank!='RECV' and Tank!='PARK' and Quantity &gt; 500]"
             use="concat(Material,'|', Tank)"/>


    <xsl:template match="/">
        <Rowsets>
            <Rowset>
                <xsl:variable name="materials" select=".//item[Tank!='RECV' and Tank!='PARK'] "/>
                <xsl:for-each select="//item[ generate-id(.) = generate-id( key('kMaterial', Material)[1]) ]" >
                    <xsl:variable name="m" select="Material" />
                        <Row>
                            <Material>
                                <xsl:value-of select="Material"/>,<xsl:value-of select="$m"/>
                            </Material>
                            <Description>
                                <xsl:value-of select="Description"/>
                            </Description>
                            <Value>
                                <xsl:for-each select="//item[ generate-id(.) =
                                                      generate-id( key('kMaterialTank', concat( $m,'|', Tank))[1])]" mode="tank" >
                                    <xsl:apply-templates select="." mode="tank" />
                                </xsl:for-each>
                            </Value>
                        </Row>
                </xsl:for-each>
            </Rowset>
        </Rowsets>
    </xsl:template>
    <xsl:template match="item" mode="tank" >
        <xsl:value-of select="Tank"/>
        <xsl:text>||</xsl:text>
    </xsl:template>

</xsl:stylesheet>

这将生成以下输出:

<?xml version="1.0" encoding="UTF-8"?>
<Rowsets>
  <Rowset>
    <Row>
      <Material>1000000079,1000000079</Material>
      <Description>330 Bulk</Description>
      <Value>T123||</Value>
    </Row>
    <Row>
      <Material>1000000196,1000000196</Material>
      <Description>340R Bulk</Description>
      <Value>T700||</Value>
    </Row>
    <Row>
      <Material>1000002754,1000002754</Material>
      <Description>43 Bulk</Description>
      <Value>T515||T517||</Value>
    </Row>
  </Rowset>
</Rowsets>
于 2013-06-13T07:02:31.330 回答