我想从连接的字符串中删除重复的值。
输入为:
<?xml version="1.0" encoding="ISO-8859-1"?>
<QL>
<QITEM>
<SERIAL>123</SERIAL>
<PROD_NAME>User/Device</PROD_NAME>
</QITEM>
<QITEM>
<SERIAL>123</SERIAL>
<PROD_NAME>User/Dev</PROD_NAME>
</QITEM>
<QITEM>
<SERIAL>123</SERIAL>
<PROD_NAME>User/Device</PROD_NAME>
</QITEM>
<QITEM>
<SERIAL>1234</SERIAL>
<PROD_NAME>45 Mbps</PROD_NAME>
</QITEM>
</QL>
<QL>
<QITEM>
<SERIAL>123</SERIAL>
<PROD_NAME>User/Device</PROD_NAME>
</QITEM>
<QITEM>
<SERIAL>123</SERIAL>
<PROD_NAME>User/Dev</PROD_NAME>
</QITEM>
<QITEM>
<SERIAL>123</SERIAL>
<PROD_NAME>User/Device</PROD_NAME>
</QITEM>
<QITEM>
<SERIAL>1234</SERIAL>
<PROD_NAME>45 Mbps</PROD_NAME>
</QITEM>
</QL>
我想连接这些值,输出应该是这样的:
<Result>
<SERIAL>123,1234</SERIAL>
<PROD_NAME>User/Dev,User/Device,45 Mbps</PROD_NAME>
</Result>
<Result>
<SERIAL>123,1234</SERIAL>
<PROD_NAME>User/Dev,User/Device,45 Mbps</PROD_NAME>
</Result>
到目前为止,我尝试使用以下模板来实现这一点:
<xsl:template name="join">
<xsl:param name="list"/>
<xsl:param name="separator"/>
<xsl:for-each select="$list">
<xsl:value-of select="."/>
<xsl:if test="position() != last()">
<xsl:value-of select="$separator"/>
</xsl:if>
</xsl:for-each>
</xsl:template>
这是给出用逗号分隔的值。
但我想获得唯一的值。
纯 XSLT 1.0 中的唯一/非重复值最好通过使用 Muenchian 分组方法来实现。
在下面的示例中,我们为要包含一组的每个项目创建一个xsl:key
。
例如,键serial
是使用自身值作为分组键的所有SERIAL
元素的组。
然后我们遍历每个组(xsl:for-each
(,只选择该组的第一个出现。
完整示例...
XML 输入
<QL>
<QITEM>
<SERIAL>123</SERIAL>
<PROD_NAME>User/Device</PROD_NAME>
</QITEM>
<QITEM>
<SERIAL>123</SERIAL>
<PROD_NAME>User/Dev</PROD_NAME>
</QITEM>
<QITEM>
<SERIAL>123</SERIAL>
<PROD_NAME>User/Device</PROD_NAME>
</QITEM>
<QITEM>
<SERIAL>1234</SERIAL>
<PROD_NAME>45 Mbps</PROD_NAME>
</QITEM>
</QL>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="serial" match="SERIAL" use="."/>
<xsl:key name="prodname" match="PROD_NAME" use="."/>
<xsl:template match="/*">
<Result>
<SERIAL>
<xsl:for-each select="QITEM/SERIAL[count(.|key('serial',.)[1])=1]">
<xsl:if test="position() > 1">,</xsl:if>
<xsl:value-of select="."/>
</xsl:for-each>
</SERIAL>
<PROD_NAME>
<xsl:for-each select="QITEM/PROD_NAME[count(.|key('prodname',.)[1])=1]">
<xsl:if test="position() > 1">,</xsl:if>
<xsl:value-of select="."/>
</xsl:for-each>
</PROD_NAME>
</Result>
</xsl:template>
</xsl:stylesheet>
XML 输出
<Result>
<SERIAL>123,1234</SERIAL>
<PROD_NAME>User/Device,User/Dev,45 Mbps</PROD_NAME>
</Result>
更新
我不确定我是否完全理解您的更新,但我认为您可以做的是使用生成的祖先 id 创建一个复合键 QL
.
XML 输入(用 doc
包装以使其格式正确。
<doc>
<QL>
<QITEM>
<SERIAL>123</SERIAL>
<PROD_NAME>User/Device</PROD_NAME>
</QITEM>
<QITEM>
<SERIAL>123</SERIAL>
<PROD_NAME>User/Dev</PROD_NAME>
</QITEM>
<QITEM>
<SERIAL>123</SERIAL>
<PROD_NAME>User/Device</PROD_NAME>
</QITEM>
<QITEM>
<SERIAL>1234</SERIAL>
<PROD_NAME>45 Mbps</PROD_NAME>
</QITEM>
</QL>
<QL>
<QITEM>
<SERIAL>123</SERIAL>
<PROD_NAME>User/Device</PROD_NAME>
</QITEM>
<QITEM>
<SERIAL>123</SERIAL>
<PROD_NAME>User/Dev</PROD_NAME>
</QITEM>
<QITEM>
<SERIAL>123</SERIAL>
<PROD_NAME>User/Device</PROD_NAME>
</QITEM>
<QITEM>
<SERIAL>1234</SERIAL>
<PROD_NAME>45 Mbps</PROD_NAME>
</QITEM>
</QL>
</doc>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="serial" match="SERIAL" use="concat(generate-id(ancestor::QL),'|',.)"/>
<xsl:key name="prodname" match="PROD_NAME" use="concat(generate-id(ancestor::QL),'|',.)"/>
<xsl:template match="QL">
<Result>
<SERIAL>
<xsl:for-each select="QITEM/SERIAL[count(.|key('serial',concat(generate-id(ancestor::QL),'|',.))[1])=1]">
<xsl:if test="position() > 1">,</xsl:if>
<xsl:value-of select="."/>
</xsl:for-each>
</SERIAL>
<PROD_NAME>
<xsl:for-each select="QITEM/PROD_NAME[count(.|key('prodname',concat(generate-id(ancestor::QL),'|',.))[1])=1]">
<xsl:if test="position() > 1">,</xsl:if>
<xsl:value-of select="."/>
</xsl:for-each>
</PROD_NAME>
</Result>
</xsl:template>
</xsl:stylesheet>
XML 输出
<Result>
<SERIAL>123,1234</SERIAL>
<PROD_NAME>User/Device,User/Dev,45 Mbps</PROD_NAME>
</Result>
<Result>
<SERIAL>123,1234</SERIAL>
<PROD_NAME>User/Device,User/Dev,45 Mbps</PROD_NAME>
</Result>