2011-07-07 1 views
2

How to remove duplicate XML nodes using XSLTとその他の関連する質問がありますが、ノード全体が重複していると重複を削除するように見えます。私がしたいのは、そのノード内の1つのプロパティが別のノード内のプロパティと一致する場合にのみノードを削除することです。xsltを使用してそのプロパティが別の用語の複製である場合に用語を削除する

私のXMLでは、2 termTypeがあります。 NdおよびPt。 Ptsを使用する必要があります。システムがNdを見つけた場合は、termNameを使用すべきではなく、代わりにrelationtermNameで参照されるPtの名前を使用する必要があります。

しかし、何かが間違っていて、一部のNdsは、参照する必要があるPtsの名前と同じ名前を持っています。これらの用語は無関係であると私は彼らに

を削除する必要があります私が持っているのNd:<term><termName>場合

<term> 
<termId>1</termId> 
<termUpdate>Add</termUpdate> 
<termName>A</termName> 
<termType>Nd</termType> 
<relation> 
    <relationType>USE</relationType> 
    <termId>2</termId> 
    <termName>A</termName> 
</relation> 
</term> 

<term> 
<termId>2</termId> 
<termUpdate>Add</termUpdate> 
<termName>A</termName> 
<termType>Pt</termType> 
</term> 

<term> 
<termId>3</termId> 
<termUpdate>Add</termUpdate> 
<termName>C</termName> 
<termType>Nd</termType> 
<relation> 
    <relationType>USE</relationType> 
    <termId>4</termId> 
    <termName>D</termName> 
</relation> 
</term> 

<term> 
<termId>4</termId> 
<termUpdate>Add</termUpdate> 
<termName>D</termName> 
<termType>Pt</termType> 
</term> 

は、通過して、それを見るために、XSLT(またはいくつかの他の方法)を使用することが可能ですは、<relation>のPt用語の<termName>と一致し、全体の用語を削除しますか? <relation>で参照されている用語は、常にPt用語です。

出力:

<term> 
<termId>2</termId> 
<termUpdate>Add</termUpdate> 
<termName>A</termName> 
<termType>Pt</termType> 
</term> 

<term> 
<termId>3</termId> 
<termUpdate>Add</termUpdate> 
<termName>C</termName> 
<termType>Nd</termType> 
<relation> 
    <relationType>USE</relationType> 
    <termId>4</termId> 
    <termName>D</termName> 
</relation> 
</term> 

<term> 
<termId>4</termId> 
<termUpdate>Add</termUpdate> 
<termName>D</termName> 
<termType>Pt</termType> 
</term> 

ありがとう!

+0

良い質問、+1。最も基本的で強力なXSLTデザインパターン(アイデンティティルールのオーバーライド)に基づいた完全で簡潔なソリューションについては、私の答えをご覧ください。 –

+0

良い質問+1。 –

答えて

1

この変換

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:key name="kPtByName" match="term[termType='Pt']" 
    use="termName"/> 

<xsl:template match="node()|@*" name="identity"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="term[termType='Nd']"> 
    <xsl:if test="not(key('kPtByName', termName))"> 
    <xsl:call-template name="identity"/> 
    </xsl:if> 
</xsl:template> 
</xsl:stylesheet> 

は(それが十分に形成するために上部要素にラップ)が設けられたXML文書に適用:

<terms> 
    <term> 
    <termId>1</termId> 
    <termUpdate>Add</termUpdate> 
    <termName>A</termName> 
    <termType>Nd</termType> 
    <relation> 
     <relationType>USE</relationType> 
     <termId>2</termId> 
     <termName>A</termName> 
    </relation> 
    </term> 

    <term> 
    <termId>2</termId> 
    <termUpdate>Add</termUpdate> 
    <termName>A</termName> 
    <termType>Pt</termType> 
    </term> 

    <term> 
    <termId>3</termId> 
    <termUpdate>Add</termUpdate> 
    <termName>C</termName> 
    <termType>Nd</termType> 
    <relation> 
     <relationType>USE</relationType> 
     <termId>4</termId> 
     <termName>D</termName> 
    </relation> 
    </term> 

    <term> 
    <termId>4</termId> 
    <termUpdate>Add</termUpdate> 
    <termName>D</termName> 
    <termType>Pt</termType> 
    </term> 
</terms> 

募集を生成します、正しい出力

<terms> 
    <term> 
     <termId>2</termId> 
     <termUpdate>Add</termUpdate> 
     <termName>A</termName> 
     <termType>Pt</termType> 
    </term> 
    <term> 
     <termId>3</termId> 
     <termUpdate>Add</termUpdate> 
     <termName>C</termName> 
     <termType>Nd</termType> 
     <relation> 
     <relationType>USE</relationType> 
     <termId>4</termId> 
     <termName>D</termName> 
     </relation> 
    </term> 
    <term> 
     <termId>4</termId> 
     <termUpdate>Add</termUpdate> 
     <termName>D</termName> 
     <termType>Pt</termType> 
    </term> 
</terms> 

説明

  1. identity ruleコピーのすべてのノード "そのまま"。

  2. IDテンプレートを上書きするテンプレートは1つだけです。 termType子の値がNdtermに一致します。このテンプレートはと同じ値のtername子があり、termTypeの子がPtの値を持つ場合にのみidentityテンプレートを呼び出します。このテストはまた、我々は与えられた条件が満たされた場合にのみ、タイプNdのノードをコピーする必要があることを考慮することによって解決することができ、便利に定義xsl:key

+0

素晴らしい、それは完璧です、あなたに戻って遅れのために謝罪、私のインターネットがダウンした。 – Charlie

+0

@Charlie:どうぞよろしくお願いいたします。 –

0

この問題を使用して行われます。次に、xsl:copy-ofを使用して、目的のノードをコピーし、XSLT関数current()を使用して、複雑なXPathを構築します。テンプレートexceludeNdは、出力ではない同じ名前を持つと場合にだけ、その関係の用語をタイプNdの用語が含まれます

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 

<xsl:include href="identity.xsl"/> 

<xsl:template match="term[termType='Nd']" name="excludeNd"> 
    <xsl:copy-of select="self::node() 
     [ not(../term 
       [ termId = current()/relation/termId ] 
        /termName = current()/termName) 
     ]"/> 
</xsl:template> 

</xsl:stylesheet> 

インクルードファイルidentity.xslは、よく知られているアイデンティティ変換を含む外部スタイルシートです。

関連する問題