XPath возвращает ноль, когда я удаляю префикс - PullRequest
2 голосов
/ 10 апреля 2011

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

Когда я удалил префиксы из файла определения 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 для каждого узла в нем.

String myExpression = "myrequest/state/value";  
Document doc = new Document(requestXML);    
Element e = doc.getRootElement();
request.setMybase(getBase((org.jdom.Element) 
            XPath.selectSingleNode(doc,myExpression)));

Ответы [ 3 ]

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

Это наиболее часто задаваемые вопросы по нескольким тегам, связанным с XPath .

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

Причина, по которой это необходимо сделать :

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

Вот нормативный текст спецификации XPath 1.0 W3C :

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

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

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

Решение

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

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

2 голосов
/ 10 апреля 2011

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

[edit] Метод 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»).

1 голос
/ 10 апреля 2011

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

Вам не нужно использовать префикс пространства имен , если вы хотите использовать 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)

...