1

こんにちは、次の XML を解析するのに助けが必要です。

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

次で終わる

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

これを行うために XSLT ドキュメントを作成しようとしていますが、まだ機能するものを見つけていません。are 内の必要な一致パラメーター (この場合は "abc") は変数であり、静的な検索可能なエンティティになることはありません。

したがって、英語では、私の XSL は次のようになります。一致する 'Unit' 値を含む親については、最後を除いて 'Unit' 内に重複する値を含むすべての先行する親 'Test' を削除します。

すべての助けに最も感謝します ありがとう

4

2 に答える 2

2

ID テンプレートを使用してドキュメント全体をコピーし、削除する要素の空のテンプレートでそのテンプレートをオーバーライドできます。要素を削除する必要があるかどうかを確認するには、その値を次の兄弟の値と<Test>比較できます。<Unit>

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

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

    <xsl:template match="/xmeml/Doc/Test[(Unit = following-sibling::Test/Unit) or (Unit = ../following-sibling::Doc/Test/Unit)][descendant::Unit2[starts-with(.,'1234')]]"/>

</xsl:stylesheet>

以下の<Unit>値がどのように発生するかについて 2 つの可能性があるため、両方の条件が明示的に記述さorれ、条件内の演算子で結合されます。

2 つの可能性とそれぞれの XPath 条件は次のとおりです。

  • <Test>現在の要素と同じ親要素の後続の要素:
    Unit = following-sibling::Test/Unit
  • 現在の要素<Test>の後続の<Doc>兄弟の<Doc>要素:
    Unit = ../following-sibling::Doc/Test/Unit

次の入力を想定します。

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

XSLT は次の出力を作成します。

<xmeml>
  <Doc>
    <Test>
      <Unit>bcd</Unit>
      <Unit2>2345</Unit2>
    </Test>
  </Doc>
  <Doc>
    <Test>
      <Unit>abc</Unit>
      <Unit2>3456</Unit2>
    </Test>
    <Test>
      <Unit>cde</Unit>
      <Unit2>3456</Unit2>
    </Test>
  </Doc>
  <Doc>
    <Test>
      <Unit>def</Unit>
      <Unit2>4567</Unit2>
    </Test>
  </Doc>
  <Doc>
    <Test>
      <Unit>abc</Unit>
      <Unit2>1234</Unit2>
    </Test>
    <Test>
      <Unit>efg</Unit>
      <Unit2>2345</Unit2>
    </Test>
  </Doc>
</xmeml>
于 2012-07-20T09:11:21.573 に答える
1

There are two different ways of performing grouping in XSLT 1.0 -- simple, using a preceding:: or following:: axis, and, the more efficient Muenchian grouping method -- using keys.

Here is the more efficient, Muenchian method:

<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="kParentByUnit" match="Test[Unit]" use="Unit"/>

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

     <xsl:template match="Test[Unit]">
       <xsl:if test=
       "generate-id()
       =
        generate-id(key('kParentByUnit', Unit)[position()=last()])">

        <xsl:call-template name="identity"/>
       </xsl:if>
     </xsl:template>
</xsl:stylesheet>

When this transformation is applied on the provided XML document:

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

the wanted, correct result is produced:

<xmeml>
   <Doc>
      <Test>
         <Unit>bcd</Unit>
         <Unit2>2345</Unit2>
      </Test>
   </Doc>
   <Doc>
      <Test>
         <Unit>cde</Unit>
         <Unit2>3456</Unit2>
      </Test>
   </Doc>
   <Doc>
      <Test>
         <Unit>def</Unit>
         <Unit2>4567</Unit2>
      </Test>
   </Doc>
   <Doc>
      <Test>
         <Unit>abc</Unit>
         <Unit2>1234</Unit2>
      </Test>
      <Test>
         <Unit>efg</Unit>
         <Unit2>2345</Unit2>
      </Test>
   </Doc>
</xmeml>
于 2012-07-20T12:16:46.217 に答える