2008-12-01 14 views
6

Ich schreibe ein XSLT-Stylesheet, um ein XML in ein anderes XML umzuwandeln. Hiernode-set in xpath

ist die vereinfachte Version der ursprünglichen 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> 

ich versuche, einen XPath zu verwenden Knoten-Set wählen von „beschreibt“ die nicht den Wert hat, der den ID-Wert von //physical/distribution gleich oder software/implementation/distribution. In obigem Fall mag ich das Knoten-Set bekommen:

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

(100 und 200 sind id Werte von //physical/distribution oder software/implementation/distribution Attribute).

schrieb ich so etwas wie:

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

Es funktioniert obiges Beispiel auf. Das Element von Datentabelle und Software ist jedoch wiederholbar. Also das xml gilt:

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

Aber mein Xslt funktioniert nicht auf dem obigen Beispiel :(

Hätten Sie etwas dagegen, etwas Licht auf diese vergießen Vielen Dank im Voraus

Jing

?!

Antwort

19

Dies ist ein häufig Fehler begangen. nie XPath's "!=" operator verwenden, wenn eine oder beide der Operanden ist/sind Knotenmenge (s).

      value != node-set

per Definition ist wahr, wenn es einen Knoten n in Knotenmenge vorhanden ist, so dass

      value zu string(n) nicht gleich

Was Sie wollen, ist, dass

      value ist nicht gleich beliebig Knoten im Knotensatz.

      value = node-set

ist wahr, wenn es mindestens einen Knoten n in Knotenmenge vorhanden ist, so dass::

     

Dies kann in der folgenden Weise ausgedrückt werden: value = string(n)

Dann

      not(value = node-set)

wahr ist, wenn es keine Knoten vorhanden ist n in Knotenmenge, so dass

      value = string(n)

Daher wird die folgende XPath-Ausdruck auswählen die gewünschten Knoten:

 
/*/*/describes[not(. = ../../*/physical/distribution/@id) 
       and 
       not(. = ../../*/implementation/distribution/@id)] 

Ich persönlich würde es vorziehen, nur ein Vergleich des Kontextknotens auf die Vereinigung der beiden Knotenmengen haben:

 
/*/*/describes 
      [not(. = (../../*/physical/distribution/@id 
        | 
         ../../*/implementation/distribution/@id 
        ) 
       ) 
      ] 

Bitte, beachten Sie, dass ich die „//“ Abkürzung nicht zu verwenden. Es ist normalerweise sehr teuer (ineffizient) und sollte nur verwendet werden, wenn wir die Struktur des XML-Dokuments nicht kennen.

Und natürlich der oben hat XPath-Ausdrücke eavaluated gegen das folgende XML-Dokument (in der Frage zur Verfügung gestellt die zweiten) zu:

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