2017-02-06 6 views
0

連結文字列から重複値を削除します。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> 

これはカンマで区切られた値を与えています。
しかし、私は一意の値を取得したい。

+0

だから ' User/Dev'値に何が起こったのですか? –

+0

申し訳ありませんが誤植でした。今質問を更新しています –

+0

あなたは何と苦労していますか? 'distinct-values(// SERIAL)'は、例えば '123,1234'というシーケンスを与えます。 –

答えて

1

純粋なXSLT 1.0の一意/個別の値は、グループ化のMuenchian Methodを使用すると最も効果的です。

以下の例では、グループを持つアイテムのそれぞれに対して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> 

UPDATE

私は、私は完全にあなたの更新を理解してないんだけど、私はあなたが行うことができると思うと、祖先QLの生成されたIDを使用して複合キーを作成することです。

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> 
+0

はいこれはうまくいきますが、実際には上記の入力が繰り返されています。そして、123,1234の値は、次のループに再び入ると表示されません。 –

+0

私は質問を更新しました。それを調べてください。私は入力と出力も追加しました。 –

+0

@srinivaskalyan - 私の更新を見てください。それがあなたの質問に答えることができない場合は、私の回答を受け入れないようにして、他の人があなたの質問を見るようにすることができます。今、それは受け入れられた答えを持っているので、ほとんどの人はそれを過ぎ去ります。 –

関連する問題