2011-04-10 6 views
2

Я использую XPath в Java под Eclipse. Я пишу веб-службу мыла, XML использует префикс и пространство имен, и я хотел удалить префикс и сохранить только пространство имен, потому что предпочитаю более читаемый XML-документ.XPath возвращает null, когда я удаляю префикс

Когда я удалил префиксы из файла определения XML и попытался запросить XML с помощью XPath, я начал получать null для каждого узла в XML!

Мой вопрос: должен ли я использовать префикс, если я хочу использовать XPath? не просто пространство имен достаточно?

<myrequest 
    xmlns="http://www.mywebsite.com/xml/webservice" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.mywebsite.com/xml/webservice Request.xsd"> 

    <state>  
     <value>demox</value> 

это как мои старты XML и когда я запрашиваю это с помощью XPath как XPath.selectSingleNode() я всегда получаю нулевой из XPath для каждого узла в нем.

+0

Хороший вопрос, +1. См. Мой ответ для полного объяснения и решения. –

ответ

2

С помощью XPath 1.0 для выбора элементов в пространстве имен вам необходимо использовать префикс в выражении XPath для определения имен элементов. Поэтому даже при очистке XML, чтобы не использовать префикс, а скорее декларация пространства имен по умолчанию в выражении XPath, вам нужно использовать префикс, привязанный к используемому по умолчанию пространству имен (http://www.mywebsite.com/xml/webservice). Как вы привязываете префикс к URI пространства имен, зависит от используемого API XPath, я не знаком с JDOM, сам проверяйте его API, как привязывать префиксы к URI пространства имен.

[редактировать] Метод http://www.jdom.org/docs/apidocs/org/jdom/xpath/XPath.html#addNamespace%28java.lang.String,%20java.lang.String%29. поэтому выберите любой префикс, который вам нравится (например, «pf»), и сделайте addNamespace("pf", "http://www.mywebsite.com/xml/webservice"), затем используйте этот префикс в вашем XPath (например, «pf: myrequest/pf: state/pf: value»).

+0

спасибо, что это работает! – Spring

3

Это самый часто задаваемый вопрос в разделе связанных с XPath тегов.

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

Причина, почему это должно быть сделано:

Всякий раз, когда есть имя без префикса в выражении XPath, XPath обрабатывает это имя как принадлежность к «нет имен».

Здесь нормативное текст из XPath 1.0 W3C Specification:.

"A QName в тесте узла преобразуется в расширенное имя с помощью деклараций пространства имен из контекста выражения Это то же самое расширение путь для имен типов элементов в начальных и конечных тегах, за исключением того, что пространство имен по умолчанию, объявленное с помощью xmlns, не используется: , если QName не имеет префикса, тогда URI пространства имен имеет значение null (это то же самое, что и имена атрибутов расширены). Это ошибка, если в QName есть префикс, для которого нет объявления пространства имен в контексте выражения ".

Поэтому, оценивая /a/b/c на документ с пространством имен по умолчанию означает: выбрать все элементы, которые находятся в «нет имен» и названы c, чей родительский элемент с именем b, который находится в «нет имен», чей родитель верхний элемент документа xml и он называется a и находится в «без пространства имен».

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

Решение:

  1. В API вашего XPath двигателя, зарегистрировать пространство имен по умолчанию и привязать к нему префикс (скажем, «х»).

  2. Теперь вы можете и должны использовать это выражение XPath: /x:myrequest/x:state/x:value вместо /myrequest/state/value

+0

спасибо, что это работает! – Spring

+0

@jan: Добро пожаловать. –

1

Мой вопрос является ли я должен использовать префикс, если я хочу использовать Xpath? isnt достаточно просто пространства имен?

Вы не должны использовать префикс пространства имен, если вы хотите использовать XPath. Просто пространства имен достаточно, но это делает ваш XPath гораздо более кратким, легче читать и поддерживать, если вы зарегистрируетесь и используете префикс пространства имен.

Вы могли использовать XPath с родовыми спичками для элементов (т.е. *) с предикатными фильтрами, заданного local-name() и namespace-uri() критерии, как это:

/*[local-name()='myrequest' 
    and namespace-uri()='http://www.mywebsite.com/xml/webservice'] 
    /*[local-name()='state' 
     and namespace-uri()='http://www.mywebsite.com/xml/webservice'] 
     /*[local-name()='value' 
     and namespace-uri()='http://www.mywebsite.com/xml/webservice'] 

Однако, это гораздо легче зарегистрировать пространство имен и использовать префикс имени в вашем XPath (например, /ws:myrequest/ws:state/ws:value)

Смежные вопросы