2015-03-15 2 views
1

Я пытаюсь разобрать XML, которые выглядят какjdom2 XPathExpression тянуть узел не в состоянии

<EvaluateHandRequest xmlns="http://www.aaa.com/aaa/schemas"> 
    <card> 
     <suit>HEARTS</suit> 
     <face>TEN</face> 
    </card> 
    <card> 
     <suit>SPADES</suit> 
     <face>KING</face> 
    </card> 
    <card> 
     <suit>HEARTS</suit> 
     <face>KING</face> 
    </card> 
    <card> 
     <suit>DIAMONDS</suit> 
     <face>TEN</face> 
    </card> 
    <card> 
     <suit>CLUBS</suit> 
     <face>TEN</face> 
    </card> 
</EvaluateHandRequest> 

И сделать это я использую XPathExpression, но я не могу вытащить результат.

SAXBuilder jdomBuilder = new SAXBuilder(); 
Document jdomDocument = jdomBuilder.build(xmlSource); 
Element element = jdomDocument.getRootElement(); 
XPathFactory xFactory = XPathFactory.instance(); 
XPathExpression xExpression = xFactory.compile("/*/*"); 
List<Element> list = xExpression.evaluate(element); 
System.out.println(list.size() + " " + list.get(0).getName());//5 card 
for (Element element2 : list) { 
    System.out.println(element2.getValue()); //proper result 
} 

Если я использую /*/* выражение во время компиляции я получаю все платы и им значение, где card находятся в верхней части иерархии. Но когда я использую /*/card, я не получаю оттуда какой-либо элемент. И я не могу вытащить результат, если я вообще напишу любое имя какого-либо узла в выражении. Какая у меня проблема?

ответ

0

В выражениях XPath всегда используется пространство имен. То есть, как они указаны (section 2.3 - курсив мой):

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

Таким образом, вам необходимо указать пространство имен, который вы хотите использовать .... прежде чем решить, что, хотя, давайте посмотрим на вашем использовании для XPath вы показать рабочий:

XPathExpression xExpression = xFactory.compile("/*/*"); 
List<Element> list = xExpression.evaluate(element); 

Это не должно компилироваться ... XPathExpression является типично типизированным классом. Вы хотите, чтобы он возвращал элементы ... Чтобы сделать это правильно, вам нужно добавить фильтр к результатам в методе компиляции. Рассмотрим текущую строку:

XPathExpression xExpression = xFactory.compile("/*/*"); 

Это должно быть:

XPathExpression<Element> xExpression = xFactory.compile("/*/*", Filters.element()); 

Это сделает все компилируется без каких-либо ошибок или предупреждений ...

Теперь, чтобы расширить XPath чтобы вытащить только элементы card, нам необходимо включить пространство имен:

Namespace aaa = Namespace.getNamespace("aaa", "http://www.aaa.com/aaa/schemas"); 

Например, чтобы получить только те элементы костюма:

Namespace aaa = Namespace.getNamespace("aaa", "http://www.aaa.com/aaa/schemas"); 
    XPathExpression<Element> xExpression = xFactory.compile(
      "/*/aaa:card/aaa:suit", Filters.element(), null, aaa); 

При наличии нескольких пространств имен, необходимых, вы можете добавить их.

Обратите внимание, что в объявлении пространства имен используется префикс aaa и, хотя префикс, используемый в вашем XML-документе, не используется, вам все равно нужно ссылаться на пространство имен в XPath. Просто потому, что нет префикса в документе не означает, что нет пространства имен .....

Читайте на Javadoc for compile(...)

+0

да, спасибо, я только что видел, как вы предыдущий aswer здесь Http: // stackoverflow.com/questions/24573282/jdom2-with-xpath-doesnt-work-with-namespace – viavad

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