набор узлов в xpath - PullRequest
       6

набор узлов в xpath

6 голосов
/ 02 декабря 2008

Я пишу таблицу стилей xslt для преобразования xml в другой xml.

Вот упрощенная версия оригинального 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 или software/implementation/distribution. В приведенном выше случае я хочу получить набор узлов:

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

(100 и 200 - значения идентификатора атрибута //physical/distribution или 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 не работает в приведенном выше примере: (

Не могли бы вы пролить свет на это? Заранее спасибо!

Jing

1 Ответ

19 голосов
/ 02 декабря 2008

Это часто совершаемая ошибка. Никогда не используйте Оператор XPath "! =" , когда один или оба операнда имеют / устанавливаются в узлах.

value != node-set

по определению истинно, если в наборе узлов существует узел n, такой что

value не равно string(n)

То, что вы хотите, это

value не равен любому узлу в наборе узлов.

Это можно выразить следующим образом:

value = node-set

истина, если существует хотя бы один узел n в наборе узлов, такой что:

value = string(n)

Тогда

not(value = node-set)

имеет значение true, если в наборе узлов не существует ни одного узла n, например,

value = string(n)

Поэтому следующее выражение XPath выберет нужные узлы :

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

Лично я предпочел бы иметь только одно сравнение узла контекста с объединением двух наборов узлов:

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

Пожалуйста, обратите внимание, что я избегаю использования сокращения "//" . Обычно это очень дорого (неэффективно) и должно использоваться, только если мы не знаем структуру XML-документа.

И, конечно, вышеприведенные выражения XPath должны быть сопоставлены со следующим 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...