我的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>
我的问题是在该领域我不想连接坦克,如果它重复。
样品应该是:
<Row>
<Material>1000002754</Material>
<Description>43 Bulk</Description>
<Value>T515||T517||</Value>
</Row>
我尝试了各种组合,却无法实现。任何人都可以帮忙吗?
答案 0 :(得分:1)
如果XML越来越大,基于密钥的解决方案(使用xslt-1.0)会更好。
但是为了解决大多数情况下的解决方案,只有具有独特的Tank值。您可以添加两个模板:
<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>
这会忽略具有相同材质和相同Tank值的任何项目。
并应用此模板替换<Value>
中的for-each循环:
<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>
答案 1 :(得分: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>
这样做你喜欢什么吗?