Как получить реальный порядок узлов из выражения xpath (java) - PullRequest
4 голосов
/ 31 марта 2011

Если у меня есть выражение XPath, которое использует preceding-sibling::, я получаю NodeList не в правильном порядке.Как я могу получить правильный заказ?Пример:

<library>
  <book name="book1">
    hello
  </book>
  <book name="book2">
    world
  </book>
  <book name="book3">
    !!!
  </book>
</library>

Если я попытаюсь оценить выражение XPath: /library/book[3]/preceding-sibling::book, я получу следующий заказ:

  • book1
  • book2

Но если я попытаюсь оценить: /library/book[3]/preceding-sibling::book[1], я получу Node:

  • book2

Итак, как я могу получить реальноепорядок из этого вида выражения:

/library/book[3]/preceding-sibling::book?

Ответы [ 3 ]

5 голосов
/ 31 марта 2011

С http://www.w3.org/TR/xpath/#predicates

Ось является либо передней, либо обратной осью.Ось, которая содержит только узел контекста или узлы, расположенные после узла контекста в порядке документа, является прямой осью.Ось, которая содержит только узел контекста или узлы, которые находятся перед узлом контекста в порядке документа, является обратной осью.Таким образом, предок, предок или самость, предшествующая и предшествующая родная оси являются обратными осями;все остальные оси являются прямыми.Поскольку собственная ось всегда содержит не более одного узла, не имеет значения, является ли она прямой или обратной осью. Позиция приближения элемента набора узлов относительно оси определяется как позиция узла в наборе узлов, упорядоченном в порядке документа, если ось является передней осью и упорядочена вобратный порядок документов, если ось является обратной осью.Первая позиция - 1.

О порядке набора результирующего узла после оценки некоторого выражения XPath с конкретным механизмом XPath, который полностью зависит от реализации.В XSLT это явно определяется, когда инструкции обрабатывают набор узлов, отсортированный в порядке документов.В XPath это то, как наборы узлов определяются в http://www.w3.org/TR/xpath/#section-Introduction:

набор узлов (неупорядоченный набор узлов без дубликатов)

Именно поэтому вВ стандартном DOM API есть настроек для получения упорядоченных и неупорядоченных результатов, а также в XQuery

3 голосов
/ 03 апреля 2011

Набор узлов не имеет порядка (наборы неупорядочены по определению). Большинство API-интерфейсов XPath представляют результат набора узлов в результате оценки выражения XPath в порядке документов , что вы наблюдаете и сообщаете в своем вопросе.

XPath - это язык запросов (только для чтения), поэтому он никогда не изменяет структуру исходного XML-документа - узлы в наборе узлов выбранных узлов совпадают со своей структурой в исходном XML-документе. В состав, помимо прочего, входит заказ .

Если вам нужно, чтобы узлы возвращались в другом порядке, отличном от их исходного порядка в документе XML, это невозможно сделать только с помощью XPath .

Для этой цели можно использовать XSLT:

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

 <xsl:template match="library">
  <xsl:apply-templates select="*[not(position() >2)]">
   <xsl:sort select="position()"
   data-type="number" order="descending"/>
  </xsl:apply-templates>
 </xsl:template>
</xsl:stylesheet>

когда это преобразование применяется к предоставленному документу XML:

<library>
    <book name="book1">     hello   </book>
    <book name="book2">     world   </book>
    <book name="book3">     !!!   </book>
</library>

желаемый, правильный результат:

<book name="book2">     world   </book>
<book name="book1">     hello   </book>
2 голосов
/ 31 марта 2011

Ось preceding-sibling индексируется в обратном порядке. preceding-sibling::*[1] - это первый предшествующий брат, то есть тот, который находится прямо перед узлом контекста.

Очевидно, Java возвращает NodeList в порядке документа. См. Ответ @ Alejandro для получения более подробной информации о порядке наборов узлов (и их представлении на языке хоста).

Так что итерация NodeList с другого конца была бы вариантом. Также попробуйте этот XPath.

/library/book[position() < 3]

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

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