Как выбрать все узлы с одинаковыми именами для разных родительских узлов? - PullRequest
4 голосов
/ 20 октября 2011

Допустим, у меня есть следующий xml:

<root>
  <person>
    <name>John</name>
  </person>
  <children>
    <person>
      <name>Jack</name>
    </person>
  </children>
</root>

Можно ли выбрать обоих людей одновременно?Предполагая, что я не знаю, что другой человек находится в теге дочерних элементов, он может легко оказаться в теге супруга (супруга) или в чем-то совершенно ином, и, возможно, в другом дочернем элементе.Я знаю, что все люди, которые мне нужны, находятся в корневом теге (не обязательно в корне документа).

Ответы [ 5 ]

10 голосов
/ 20 октября 2011

Вы можете использовать

//person

или

//*[local-name()='person']

, чтобы найти любые person элементы в документе, но будьте осторожны - некоторые процессоры xsl (например, Microsoft), производительностьдвойной косой черты может быть плохим для больших xml документов, потому что все узлы в документе должны быть оценены.

Редактировать:
Если вы знаете, что есть только 2 пути к 'person ', тогда вы можете полностью избежать //:

<xsl:for-each select="/root/person | /root/children/person">
    <outputPerson>
        <xsl:value-of select="name/text()" />
    </outputPerson>
</xsl:for-each>

ИГНОСТИЧЕСКОЕ пространство имен:

<xsl:for-each select="/*[local-name()='root']/*[local-name()='person'] 
  | /*[local-name()='root']/*[local-name()='children']/*[local-name()='person']">
3 голосов
/ 20 октября 2011

В ответе Петра Иванова определение // неверно .

Вот правильное определение из спецификации XPath 1.0 W3C :

// - это сокращение от /descendant-or-self::node()/

1 голос
/ 20 октября 2011

Как указано в nonnb, производительность двойной косой черты в больших XML-документах низкая.

Таким образом, //name сделает свое дело, но может принести гораздо больше элементов, которые вы ожидаете. Кроме того, представьте, что внутри вашего корневого элемента есть элементы, которые не являются лицами, у которых может быть элемент потомков с именем name , в соответствии с вашим вопросом вы не хотите их поднимать, //name приведет их до.

Вы должны привязать свой контекстный узел на максимуме, чтобы производительность XPath была оптимальной.

Для этого точного документа я бы использовал

/root/descendant::person/name

Надеюсь, это поможет,

1 голос
/ 20 октября 2011

Или вы можете использовать:

корень // лицо

Таким образом, вы ищете персию только в корневом элементе

1 голос
/ 20 октября 2011
//name

будет соответствовать обоим, независимо от того, где они находятся в дереве XML.

// Выбирает узлы в документе из текущего узла, которые соответствуют выбору, независимо от того, где они находятся ( ссылка )

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...