7

xml を別の xml に変換する xslt スタイル シートを作成しています。

元の xml の簡易版は次のとおりです。

 <eml>
        <datatable>
                 <physical>
                     <distribution id="100"/>
                 </physical>
       </datatable>                 

       <software>
           <implementation>
              <distribution id="200"/>
            </implementation>
      </software>
     <additionalMetadata>
        <describes>100</describes>
        <describes>200</describes>
        <describes>300</describes>
        <describes>400</describes>
    </additionalMetadata>
   </eml>

Xpath を使用して、//physical/distributionまたはの id 値と等しい値を持たない「記述」のノード セットを選択しようとしましたsoftware/implementation/distribution。上記の場合、ノードセットを取得したい:

   <deseribes>300</describes>
   <deseribes>400</describes>

(100 と 200 は//physical/distributionまたは の属性 ID 値ですsoftware/implementation/distribution)。

私は次のようなものを書きました:

<xsl:with-param name="describes-list" 
                select="./describes[//physical/distribution/@id !=. and
                             //software/implementation/distribution/@id != .] "/>

上記の例で動作します。ただし、データテーブルとソフトウェアの要素は繰り返し可能です。したがって、この xml は有効です。

<eml>
    <datatable>
             <physical>
                 <distribution id="100"/>
             </physical>
   </datatable> 

  <datatable>
             <physical>
                 <distribution id="300"/>
             </physical>
   </datatable>                

   <software>
       <implementation>
          <distribution id="200"/>
       </implementation>
  </software>
 <additionalMetadata>
    <describes>100</describes>
    <describes>200</describes>
    <describes>300</describes>
    <describes>400</describes>
  </additionalMetadata>
</eml>

しかし、私の xslt は上記の例では機能しません :(

これに光を当てていただけませんか?前もって感謝します!

ジン

4

1 に答える 1

20

これはよく犯される間違いです。オペランドの一方または両方がノード セットである場合は、XPath の「!=」演算子を使用しないでください。

   value != node-set

ノードセットにノード n が存在する場合、定義により真です。

   value等しくないstring(n)

あなたが欲しいのはそれです

   valuenode-set 内のどのノードとも等しくありません。

これは次のように表現できます。

   value = node-set

node-set に少なくとも 1 つのノード n が存在する場合、次のように true になります。

   value = string(n)

それで

   not(value = node-set)

node-set にノード n が存在しない場合、真です。

   value = string(n)

したがって、次の XPath 式は目的のノードを選択します

/*/*/describes[not(. = ../../*/physical/distribution/@id)
              と
                ない (. = ../../*/実装/配布/@id)]

個人的には、コンテキスト ノードと 2 つのノード セットの結合を 1 つだけ比較することを好みます。

/*/*/説明
            [not(. = (../../*/physical/distribution/@id
                    | |
                      ../../*/実装/配布/@id
                     )
                 )
            ]

「//」の省略形を使用しないことに注意してください。通常、これは非常にコストがかかる (非効率的) ため、XML ドキュメントの構造がわからない場合にのみ使用する必要があります。

そしてもちろん、上記の XPath 式は、次の XML ドキュメント (質問で提供されている 2 番目のドキュメント) に対して評価する必要があります。

<eml>
    <データテーブル>
        <物理>
            <配布ID="100"/>
        </物理>
    </データテーブル>
    <データテーブル>
        <物理>
            <配布ID="300"/>
        </物理>
    </データテーブル>
    <ソフトウェア>
        <実装>
            <配布ID="200"/>
        </実装>
    </ソフトウェア>
    <追加メタデータ>
        <describes>100</describes>
        <describes>200</describes>
        <describes>300</describes>
        <describes>400</describes>
    </additionalMetadata>
</eml>
于 2008-12-02T00:01:59.847 に答える