从 XSLT 中的串联字符串中删除重复值



我想从连接的字符串中删除重复的值。

输入为:

 <?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>

相关内容

  • 没有找到相关文章

最新更新