2015-11-30 2 views
1

Я использую S9API с Saxon 9.7 HE, и у меня есть объект NodeInfo. Мне нужно создать инструкцию xPath, которая однозначно соответствует этому NodeInfo. Это достаточно легко, чтобы получить префикс, имя узла и родителя:Как создать инструкцию xPath из NodeInfo?

String prefix = node.getPrefix(); 
String localPart = node.getLocalPart(); 
NodeInfo parent = node.getParent(); 

Так что я могу ходить вверх по дереву, строить XPATH как я иду. Но то, что я не могу найти, - это любой способ получить информацию о позиционном предикате. IOW, этого недостаточно:

/persons/person/child 

потому что он может соответствовать нескольким дочерним элементам. Мне нужно создать:

/persons/person[2]/child[1] 

который будет соответствовать только одному дочернему элементу. Любые идеи о том, как получить информацию о позиционном предикате? Или, может быть, есть лучший способ сделать это вообще?

Кстати, для тех, кто использует общий DOM, а не S9API, вот простое решение этой проблемы: http://practicalxml.sourceforge.net/apidocs/net/sf/practicalxml/DomUtil.html#getAbsolutePath(org.w3c.dom.Element)


Редактировать: ответ работы @Michael Кея. Для того, чтобы добавить мясо к нему:

XPathExpression xPathExpression = xPath.compile("./path()"); 
List matches = (List) xPathExpression.evaluate(node, XPathConstants.NODESET); 
String pathToNode = matches.get(0).toString(); 
// If you want to remove the expanded QName syntax: 
pathToNode = pathToNode.replaceAll("Q\\{.*?\\}", ""); 

Это должно быть сделано, используя тот же объект XPATH, который ранее использовался для приобретения объекта NodeInfo.

ответ

2

В XPath 3.0 вы можете использовать fn: path().

Ранние саксонские релизы предлагают саксон: путь().

Задача здесь заключается в обработке пространств имен. fn: path() возвращает путь, который нечувствителен к привязкам префикса к пространству имен с использованием нового синтаксиса расширенного QName

/Q{}persons/Q{}person[2]/Q{}child[1] 
+0

Благодарим вас за альтернативный подход. Я никогда не рассматривал использование xPath для решения проблемы. Вопрос: Возможно ли вернуть xPath, который не является * в расширенном синтаксисе QName? –

+1

Нет, если вы хотите что-то другое, вам нужно самому закодировать его. Но достаточно легко получить позицию: 'let $ n: =. return 1 + count (previous-sibling :: * [node-name (.) = node-name ($ n)]) ' –

+0

Упрощенный ответ: используйте силу Java: pathToNode = pathToNode.replaceAll (" Q \\ {. *? \\} "," ");'. –