0

我的 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>
    </item>
    <item>
        <Material>1000000079</Material>
        <Description>330 Bulk</Description>
        <Tank>T123</Tank>
        <Batch>2013225301</Batch>
    </item>
    <item>
        <Material>1000000196</Material>
        <Description>340R Bulk</Description>
        <Tank>T700</Tank>
        <Batch>1000188378</Batch>
    </item>
    <item>
        <Material>1000002754</Material>
        <Description>43 Bulk</Description>
        <Tank>T515</Tank>
        <Batch>2013180125</Batch>
    </item>
    <item>
        <Material>1000002754</Material>
        <Description>43 Bulk</Description>
        <Tank>T515</Tank>
        <Batch>2013203124</Batch>
    </item>
    <item>
        <Material>1000002754</Material>
        <Description>43 Bulk</Description>
        <Tank>T515</Tank>
        <Batch>2013214839</Batch>
    </item>
    <item>
        <Material>1000002754</Material>
        <Description>OGA 72043 Bulk</Description>
        <Tank>T517</Tank>
        <Batch>2013214342</Batch>
    </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||T515||T515||T517||</Value>
        </Row>
    </Rowset>
</Rowsets>

我的问题在于如果重复,我不想连接 Tank。

样本应该是:

<Row>
                <Material>1000002754</Material>
                <Description>43 Bulk</Description>
                <Value>T515||T517||</Value>
            </Row>

我尝试了各种组合,但无法实现。有人可以帮忙吗?

4

2 回答 2

1

如果 XML 变得更大,那么基于密钥的解决方案(使用 xslt-1.0)会更好。

但是要使解决方案大部分保持原样,只有独特的坦克价值。您可以添加两个模板:

<xsl:template match="item" mode="tank" />
<xsl:template match="item[not(Material = preceding::item/Material and Tank =  preceding::item/Tank)]" mode="tank" >
    <xsl:value-of select="Tank"/>
    <xsl:text>||</xsl:text>
</xsl:template>

这会忽略任何具有相同材料和相同坦克值的项目。

并应用此模板代替 for-each 循环<Value>

<xsl:apply-templates select="$materials[Material=current()/Material ]" mode="tank" />

因此试试这个:

<?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:apply-templates select="$materials[Material=current()/Material ]" mode="tank" />
                            </Value>
                        </Row>
                    </xsl:if>
                </xsl:for-each>
            </Rowset>
        </Rowsets>
    </xsl:template>
    <xsl:template match="item" mode="tank" />
    <xsl:template match="item[not(Material = preceding::item/Material and Tank =  preceding::item/Tank)]" mode="tank" >
        <xsl:value-of select="Tank"/>
        <xsl:text>||</xsl:text>
    </xsl:template>

</xsl:stylesheet>

这将生成以下输出:

<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>T515||T517||</Value>
    </Row>
  </Rowset>
</Rowsets>
于 2013-06-12T08:47:15.263 回答
1

对于 XSLT 1.0,您希望使用称为Muenchian grouping的东西。我假设您可能也希望保留替代描述并将您的 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="/">
    <xsl:variable name="materials" select="BATCHES/item[Tank!='RECV' and Tank!='PARK']"/>

    <Rowsets>
      <Rowset>
        <xsl:for-each select="$materials[not(Material=preceding-sibling::item/Material)]">
          <Row>
            <xsl:variable name="items" select="//item[Material=current()/Material]"/>
            <xsl:variable name="distinct-descriptions" select="$items[not(Description=preceding-sibling::item/Description)]"/>
            <xsl:variable name="distinct-tanks" select="$items[not(Tank=preceding-sibling::item/Tank)]"/>

            <Material><xsl:value-of select="Material"/></Material>
            <Description>
              <xsl:for-each select="$distinct-descriptions">
                  <xsl:if test="position() != 1">||</xsl:if>
                  <xsl:value-of select="Description"/>
              </xsl:for-each>
            </Description>
            <Value>
              <xsl:for-each select="$distinct-tanks">
                <xsl:if test="position() != 1">||</xsl:if>
                <xsl:value-of select="Tank"/>
              </xsl:for-each>
            </Value>
          </Row>
        </xsl:for-each>
      </Rowset>
    </Rowsets>
  </xsl:template>
</xsl:stylesheet>

这会做你想要的吗?

于 2013-06-12T09:13:46.157 回答