-1

xslt で変換したい XML があります。入力はこんな感じ。

<xmeml>
<Doc>
    <Test>
        <Unit>abc</Unit>
        <Unit2>1234</Unit2>
        <Unit3>tuvw</Unit3>
    </Test>
    <Test>
        <Unit>bcd</Unit>
        <Unit2>2345</Unit2>
        <Unit3>wxyz</Unit3>
    </Test>
</Doc>
<Doc>
    <Test>
        <Unit>abc</Unit>
        <Unit2>3456</Unit2>
        <Unit3>wxyz</Unit3>
    </Test>
    <Test>
        <Unit>cde</Unit>
        <Unit2>3456</Unit2>
        <Unit3>wxyz</Unit3>
    </Test> 
</Doc>
<Doc>
    <Test>
        <Unit>abc</Unit>
        <Unit2>1234</Unit2>
        <Unit3>wxyz</Unit3>
    </Test>
    <Test>
        <Unit>def</Unit>
        <Unit2>4567</Unit2>
        <Unit3>wxyz</Unit3>
    </Test> 
</Doc>
<Doc>
    <Test>
        <Unit>abc</Unit>
        <Unit2>1234</Unit2>
        <Unit3>uvwx</Unit3>
    </Test>
    <Test>
        <Unit>efg</Unit>
        <Unit2>2345</Unit2>
        <Unit3>wxyz</Unit3>
    </Test> 
</Doc>
</xmeml>

出力は次のようになります。

<xmeml>
<Doc>
    <Test>
        <Unit>bcd</Unit>
        <Unit2>2345</Unit2>
        <Unit3>wxyz</Unit3>
    </Test>
</Doc>
<Doc>
    <Test>
        <Unit>abc</Unit>
        <Unit2>3456</Unit2>
        <Unit3>wxyz</Unit3>
    </Test>
    <Test>
        <Unit>cde</Unit>
        <Unit2>3456</Unit2>
        <Unit3>wxyz</Unit3>
    </Test> 
</Doc>
<Doc>
    <Test>
        <Unit>abc</Unit>
        <Unit2>1234</Unit2>
        <Unit3>wxyz</Unit3>
    </Test>
    <Test>
        <Unit>def</Unit>
        <Unit2>4567</Unit2>
        <Unit3>wxyz</Unit3>
    </Test> 
</Doc>
<Doc>
    <Test>
        <Unit>efg</Unit>
        <Unit2>2345</Unit2>
        <Unit3>wxyz</Unit3>
    </Test> 
</Doc>
</xmeml>

次の条件に一致するテスト ノードを削除したいと考えています。- Unit3 の子ノードは、tuv または uvw で始まります。- AND ユニットとユニット 2 の両方の値が、別のテスト ノードで繰り返されているか複製されている場合

よろしくお願いします。

4

2 に答える 2

1

この変換(Muenchianグループ化ベース):

<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="kTest"
   match="Test[starts-with(Unit3, 'tuv') or starts-with(Unit3, 'uvw')]"
          use="concat(Unit, '+', Unit2)"/>

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

 <xsl:template match=
  "Test[starts-with(Unit3, 'tuv') or starts-with(Unit3, 'uvw')]
    [not(generate-id()
    =
     generate-id(key('kTest', concat(Unit, '+', Unit2))[last()]))]"/>
</xsl:stylesheet>

提供されたXMLドキュメントに適用した場合

<xmeml>
    <Doc>
        <Test>
            <Unit>abc</Unit>
            <Unit2>1234</Unit2>
            <Unit3>tuvw</Unit3>
        </Test>
        <Test>
            <Unit>bcd</Unit>
            <Unit2>2345</Unit2>
            <Unit3>wxyz</Unit3>
        </Test>
    </Doc>
    <Doc>
        <Test>
            <Unit>abc</Unit>
            <Unit2>3456</Unit2>
            <Unit3>wxyz</Unit3>
        </Test>
        <Test>
            <Unit>cde</Unit>
            <Unit2>3456</Unit2>
            <Unit3>wxyz</Unit3>
        </Test>
    </Doc>
    <Doc>
        <Test>
            <Unit>abc</Unit>
            <Unit2>1234</Unit2>
            <Unit3>wxyz</Unit3>
        </Test>
        <Test>
            <Unit>def</Unit>
            <Unit2>4567</Unit2>
            <Unit3>wxyz</Unit3>
        </Test>
    </Doc>
    <Doc>
        <Test>
            <Unit>abc</Unit>
            <Unit2>1234</Unit2>
            <Unit3>uvwx</Unit3>
        </Test>
        <Test>
            <Unit>efg</Unit>
            <Unit2>2345</Unit2>
            <Unit3>wxyz</Unit3>
        </Test>
    </Doc>
</xmeml>

正しい結果を生成します(すべての要件を実装します):

<xmeml>
   <Doc>
      <Test>
         <Unit>bcd</Unit>
         <Unit2>2345</Unit2>
         <Unit3>wxyz</Unit3>
      </Test>
   </Doc>
   <Doc>
      <Test>
         <Unit>abc</Unit>
         <Unit2>3456</Unit2>
         <Unit3>wxyz</Unit3>
      </Test>
      <Test>
         <Unit>cde</Unit>
         <Unit2>3456</Unit2>
         <Unit3>wxyz</Unit3>
      </Test>
   </Doc>
   <Doc>
      <Test>
         <Unit>abc</Unit>
         <Unit2>1234</Unit2>
         <Unit3>wxyz</Unit3>
      </Test>
      <Test>
         <Unit>def</Unit>
         <Unit2>4567</Unit2>
         <Unit3>wxyz</Unit3>
      </Test>
   </Doc>
   <Doc>
      <Test>
         <Unit>abc</Unit>
         <Unit2>1234</Unit2>
         <Unit3>uvwx</Unit3>
      </Test>
      <Test>
         <Unit>efg</Unit>
         <Unit2>2345</Unit2>
         <Unit3>wxyz</Unit3>
      </Test>
   </Doc>
</xmeml>

更新

OPには問題の独自の解釈がありますが、これはあいまいであり、正確に定義されていません。

かなりの推測で、これが彼が望むかもしれないものです...:

<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="kTest"
   match="Test" use="concat(Unit, '+', Unit2)"/>

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

 <xsl:template match=
  "Test[starts-with(Unit3, 'tuv') or starts-with(Unit3, 'uvw')]
    [not(generate-id()
    =
     generate-id(key('kTest', concat(Unit, '+', Unit2))
                                     [not(position()=1)])
                )]"/>
</xsl:stylesheet>

この変換が提供されたXMLドキュメント(上記)に適用されると、結果はOPが目的の結果であると信じているものと同じになります。

<xmeml>
   <Doc>
      <Test>
         <Unit>bcd</Unit>
         <Unit2>2345</Unit2>
         <Unit3>wxyz</Unit3>
      </Test>
   </Doc>
   <Doc>
      <Test>
         <Unit>abc</Unit>
         <Unit2>3456</Unit2>
         <Unit3>wxyz</Unit3>
      </Test>
      <Test>
         <Unit>cde</Unit>
         <Unit2>3456</Unit2>
         <Unit3>wxyz</Unit3>
      </Test>
   </Doc>
   <Doc>
      <Test>
         <Unit>abc</Unit>
         <Unit2>1234</Unit2>
         <Unit3>wxyz</Unit3>
      </Test>
      <Test>
         <Unit>def</Unit>
         <Unit2>4567</Unit2>
         <Unit3>wxyz</Unit3>
      </Test>
   </Doc>
   <Doc>
      <Test>
         <Unit>efg</Unit>
         <Unit2>2345</Unit2>
         <Unit3>wxyz</Unit3>
      </Test>
   </Doc>
</xmeml>
于 2012-07-22T03:19:01.943 に答える
1

Dimitreのソリューションのこの微調整はどうですか...

<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="kTest" match="Test" use="concat(Unit, '+', Unit2)"/>

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

 <xsl:template match=
  "Test[key('kTest', concat(Unit, '+', Unit2))[2]]
   [starts-with(Unit3, 'tuv') or starts-with(Unit3, 'uvw')]"/>
</xsl:stylesheet>

私が理解しているように、変換のルールは次のとおりです。

  1. 以下に示す場合を除き、すべてのノードをそのままコピーします。
  2. 次のプロパティを持つすべてのテスト ノードを除外します。

2.1 ドキュメント内に別の Test ノード (Test(other) と呼ぶ) が存在し、次のようになります。

  (Test(reference) / Unit = Test(other) / Unit)   AND
  (Test(reference) / Unit2 = Test(other) / Unit2)

2.2 参照 Test ノードの Unit3 の子が tuv または uvw で始まる

この出力は、投稿された OP とまったく同じです。興味深いことに、私が問題を正しく理解していれば、Dimitre は最近、XSL comparison of nodes であなたの問題とほぼ同じ問題の解決策を提供しました。繰り返しますが、私があなたの問題を正しく理解していれば、タイトルは誤解を招くものです。「重複の削除」は、通常、 (1,2,2,3) --> (1,2,3) のように、重複排除を意味します。一方、 (1,2,2,3) --> (1,3) のような必要なものは、一般に「一意のノード/値を選択する」と説明されています。

于 2012-07-22T06:24:05.280 に答える