如果您想进一步了解 XSLT 的复杂性,您可能有兴趣了解一种称为Muenchian Grouping的技术,该技术可用于解决您的问题。要获得不同的行,您可以按attribute1有效地将它们分组,然后为每个组选择组中的第一个元素。(或者丢弃不是第一个的元素)。Muenchian Grouping 是在 XSLT 1.0 中实现这一目标的最有效方式。
在这种情况下,您首先定义一个键来指示您的组,在您的情况下是行元素,按attribute1分组
<xsl:key name="row" match="row" use="@attribute1" />
如果您想选择不同的行元素,您将选择在给定属性的键中首先出现的行元素1
<xsl:apply-templates select="row[generate-id() = generate-id(key('row', @attribute1)[1])]" />
或者,您可以有一个模板来忽略重复的行元素(即不是组中的第一个)
<xsl:template match="row[generate-id() != generate-id(key('row', @attribute1)[1])]" />
试试这个 XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="row" match="row" use="@attribute1" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="row[generate-id() != generate-id(key('row', @attribute1)[1])]" />
</xsl:stylesheet>
应用于以下 XML 时
<rows>
<row attribute1="1" attribute2="something" attribute3="somevalue" />
<row attribute1="1" attribute2="something" attribute3="somevalue" />
<row attribute1="2" attribute2="anotherthing" attribute3="somevalue" />
</rows>
以下是输出
<rows>
<row attribute1="1" attribute2="something" attribute3="somevalue"></row>
<row attribute1="2" attribute2="anotherthing" attribute3="somevalue"></row>
</rows>
XSLT 可以很容易地扩展为重命名属性,或者排除它们,如 ljdelight 的回答中所述。此外,如果您想在测试中包含第二个属性,您可以像这样扩展您的密钥:
<xsl:key name="row" match="row" use="concat(@attribute1, '|', @attribute3)" />
并且忽略重复项,模板看起来像这样
<xsl:template match="row
[generate-id() != generate-id(key('row', concat(@attribute1, '|', @attribute3))[1])]" />
这里唯一需要注意的是管道字符 | 的使用。作为分隔符。如果需要,这可以是任何其他字符,只要它不出现在属性值中即可。