JDOM, XPath и взаимодействия пространства имен - PullRequest
4 голосов
/ 05 июля 2010

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

  <srv:getPricebookByCompanyResponse xmlns:srv="http://ess.com/ws/srv">
     <srv:Pricebook>
        <srv:PricebookName>Demo Operator Pricebook</srv:PricebookName>
        <srv:PricebookItems>
           <srv:PricebookItem>
              <srv:ItemName>Demo Wifi</srv:ItemName>
              <srv:ProductCode>DemoWifi</srv:ProductCode>
              <srv:ItemPrice>15</srv:ItemPrice>
              <srv:ItemCost>10</srv:ItemCost>
           </srv:PricebookItem>
           <srv:PricebookItem>
              <srv:ItemName>1Mb DIA</srv:ItemName>
              <srv:ProductCode>Demo1MbDIA</srv:ProductCode>
              <srv:ItemPrice>20</srv:ItemPrice>
              <srv:ItemCost>15</srv:ItemCost>
           </srv:PricebookItem>
        </srv:PricebookItems>
     </srv:Pricebook>
  </srv:getPricebookByCompanyResponse>

Обычно я бы просто использовал выражение, такое как // srv: ItemCost, чтобы идентифицировать эти элементы, что прекрасно работает с другими документами, однако здесь он постоянно возвращает 0 узлов в списке.Вот код, который я использовал:

Namespace ns = Namespace.getNamespace("srv","http://ess.com/ws/srv");   
XPath filterXpression = XPath.newInstance("//ItemCost");
filterXpression.addNamespace(ns);   
List nodes = filterXpression.selectNodes(response);

Где response - это элемент JDOM, содержащий приведенный выше фрагмент XML (проверяется с помощью XMLOutputter).Узлы постоянно имеет размер () == 0 при анализе этого документа.Используя синтаксический анализатор XPath в Eclipse для того же документа, это выражение также не работает.После некоторых копаний я заставил оценщик Eclipse работать со следующим выражением: // * [local-name () = 'ItemCost'], однако замена // srv: ItemCost в коде Java на это все еще не принесла результатов.Еще одна вещь, которую я заметил, - если я удалю объявление пространства имен из XML, // srv: ItemCost будет корректно разрешаться в анализаторе Eclipse, но я не могу удалить его из XML.Я почесал свою голову в течение наших часов на этом сейчас, и был бы очень признателен, чтобы подтолкнуть в правильном направлении.

Большое спасибо

Редактировать: Исправлен код -

Document build = new Document(response);
XPath filterXpression = XPath.newInstance("//srv:ItemCost");
List nodes = filterXpression.selectNodes(build);

1 Ответ

1 голос
/ 05 июля 2010

Странно, действительно ... Я проверил на моей стороне jdom, и ваш фрагмент дал пустой список, следующие работы как задумано:

public static void main(String[] args) throws JDOMException, IOException {
    File xmlFile = new File("sample.xml");
    SAXBuilder builder = new SAXBuilder();
    Document build = builder.build(xmlFile);        
    XPath filterXpression = XPath.newInstance("//srv:ItemCost");
    System.out.println(filterXpression.getXPath());
    List nodes = filterXpression.selectNodes(build);        
    System.out.println(nodes.size());
}

Производит вывод:

//srv:ItemCost
2
...