2016-02-11 2 views
0

Я пытаюсь выяснить, как перемещаться в область xml, которая использует пространства имен. Используя базовый xpath, я могу отлично подойти к узлу детали сообщения, но я не уверен, что мне нужно сделать с точки зрения доступа к этому блоку, поскольку все внутри использует пространства имен. Пожалуйста, кто-нибудь может помочь?Навигация по XML с помощью XPATH с другим пространством имен

Благодаря

<?xml version="1.0" encoding="UTF-8"?> 
    <Message> 
     <MessageList> 
      <MessageCount>2</MessageCount> 
      <DateTimeStamp>2016-02-11T12:50:26</DateTimeStamp> 
      <MessageDetail> 
       <MessageID>2332445456767</MessageID> 
       <Env:MessageContainer xmlns:Env="http://www.somesite.com/schema/v1.0/envelope" xmlns:BS="http://www.somesite.com/schema/v1.0/BusinessServices"> 
        <Env:MessageParties> 
public List<String> getRefs(String xmlMessageToSend) 
{ 
    try 
    { 
     Document doc = createDocument(xmlMessageToSend.getBytes()); 
     XPath xpath = xPathFactory.newXPath(); 
     xpath.setNamespaceContext(new NamespaceContext() { 

      @Override 
      public String getNamespaceURI(String prefix) 
      { 
       if (prefix == null) 
        throw new NullPointerException("Null prefix"); 
       else if ("Env".equals(prefix)) 
        return "http://www.om.com/schema/v1.0/envelope"; 
       else if ("BS".equals(prefix)) 
        return "http://www.o.com/schema/v1.0/BusinessServices"; 

       return XMLConstants.NULL_NS_URI; 
      } 

      @Override 
      public Iterator getPrefixes(String namespaceURI) 
      { 
       throw new UnsupportedOperationException(); 
      } 

      @Override 
      public String getPrefix(String namespaceURI) 
      { 
       throw new UnsupportedOperationException(); 
      } 

     }); 
     XPathExpression exp = xpath 
       .compile("/Message/MessageList/MessageDetail/Env:MessageContainer"); 
     Node result = (Node)exp.evaluate(doc, XPathConstants.NODE); 
     System.out.println(result.getTextContent()); 
    } 
    catch (XPathExpressionException | SAXException | IOException | ParserConfigurationException e) 
    { 
     e.printStackTrace(); 
    } 

    return new ArrayList<String>(); 
} 
+1

Используйте префикс пространства имен с NODENAME. Например: :: Env: MessageContainer – Jagrut

+0

Вы также можете использовать общий путь. // Messagedetail/* [2]/* [1] ... – Helmer

+0

@Jagrut, который не работал – Biscuit128

ответ

0

Вы не говорите, что вы используете для навигации документа, но, как правило, должен быть путь в API все, что вы используя для вас объявление префикса пространства имен, соответствующего объявлению на Env: MessageContainer. Затем вы можете использовать этот префикс в XPath, например. //e:MessageContainer (при условии, что вы отобразили «e» на "http://www.somesite.com/schema/v1.0/envelope").

0

Вам необходимо использовать префикс сообщения в выражении XPath. Например,

//foo:MessageContainer 

Этот префикс не должен быть тот же префикс, используемый для пространства имен URI, как в исходном документе. Здесь я использовал префикс foo, хотя в вашем документе был Env. Пока оба префикса сопоставляются с одним и тем же URI (http://www.somesite.com/schema/v1.0/envelope в этом примере), XPath будет соответствовать.

Как именно вы привязываете этот префикс к требуемому URI пространства имен, зависит от языка хоста, на котором встроено выражение XPath. Например, в XSLT вы просто объявляете соответствующие префиксы в таблице стилей XSLT, как и в любом другом документе XML. В отличие от XOM, вы должны предоставить объект XPathContext, который соответствующим образом отображает префиксы пространства имен. И так далее для других языков и API.

0

Вы можете получить доступ к своим элементам, например.

//Env:MessageContainer 

Но чтобы достичь этого, ваш xmlns:Env="http://www.somesite.com/schema/v1.0/envelope" xmlns:BS="http://www.somesite.com/schema/v1.0/BusinessServices" должен быть определен в <root> элементе вместо (или в дополнение к) в <Env:MessageContainer> элемента.

Но если вы не можете изменить исходный XML, правильным решением было бы всеобъемлющее стиль написать то же самое, что и выше:

//*[local-name()='MessageContainer'][namespace-uri()='http://www.somesite.com/schema/v1.0/envelope'] 
Смежные вопросы