2011-07-20 22 views
6

Otrzymuję węzeł zerowy, gdy próbuję parsować plik XML.Powrót XPath dla "węzła", gdy isNameSpaceAware i isValidating są "prawdziwe"

XPath xPath = XPathFactory.newInstance().newXPath(); 
    Node node = null; 
    try { 
     node = (Node) xPath.evaluate(
       "/mynode", 
       doc, 
       XPathConstants.NODE); 

Jestem stoi ten problem tylko w CASE-
1. DocumentBuilderFactory- setNameSpaceAware prawda
2. DocumentBuilderFactory- setValidating jest prawdą.

Jeśli są ustawione na fałsz, otrzymuję poprawne wyniki. Czy ktoś może mi pomóc w zrozumieniu, jaka jest relacja ustawienia tych atrybutów na fałsz? (I zostały sprawdzone this pytanie, ale nie usunąć moje wątpliwości)

Oto XML-

<?xml version="1.0" encoding="UTF-8"?> 
<mynode xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.example.com" xsi:schemaLocation="http://www.example.com example.xsd"> 
    <name>TargetName</name> 
    <desc>desc goes here</desc> 
    <pack>my.this</pack> 
    <object>my.ExampleObject</object> 
    <properties> 
     <attrib> 
      <name>id</name> 
      <value>ZZZ</value> 
     </attrib> 
     <attrib> 
      <name>ind</name> 
      <value>X</value> 
     </attrib> 
    </properties> 
    <children> 
     <child> 
      <name>childnodename</name> 
      <desc>description goes here</desc> 
      <invalues> 
       <scope>ALL</scope> 
      </invalues> 
      <outvalues> 
       <scope>ALL</scope> 
      </outvalues> 
      <akey> 
       <aname>AAA</aname> 
       <key></key> 
      </akey> 
      <msg> 
       <success>code1</success> 
       <failure>code2</failure> 
      </msg> 
     </child> 
    </children> 
</mynode> 

Odpowiedz

4

Najszybszym rozwiązaniem jest nie setNamespaceAware(true); :-) Jednak jeśli chcesz nazw świadomy XPath następnie masz natknął klasycznego problemu - XPath: Is there a way to set a default namespace for queries?, że XPath nie obsługuje koncepcję domyślnej przestrzeni nazw.

Tak więc XPath musi używać prefiksu przestrzeni nazw, aby zapytanie mogło znaleźć dowolne węzły. Można jednak ustawić instancję NamespaceContext w instancji XPath, aby rozpoznać prefiks przestrzeni nazw lub domyślną przestrzeń nazw na identyfikator URI. Jednym ze sposobów, aby to zrobić, na przykład:

import java.util.*; 
import java.io.ByteArrayInputStream; 
import javax.xml.namespace.NamespaceContext; 
import javax.xml.parsers.*; 
import javax.xml.xpath.*; 
import org.w3c.dom.*; 

public class XmlParse { 
    public static void main(String[] args) throws Exception { 

     String xml = 
      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" + 
      "<mynode xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.example.com\" xsi:schemaLocation=\"http://www.example.com example.xsd\">" + 
      "<name>TargetName</name>" + 
      "</mynode>"; 
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     dbf.setNamespaceAware(true); 
     DocumentBuilder builder = dbf.newDocumentBuilder(); 
     Document doc = builder.parse(new ByteArrayInputStream(xml.getBytes())); 

     final String nonameNamespace = doc.getFirstChild().getNamespaceURI(); 

     NamespaceContext ctx = new NamespaceContext() { 
      public String getNamespaceURI(String prefix) { 
       String uri = null; 
       if (prefix.equals("n")) { 
        uri = nonameNamespace; 
       } 
       return uri; 
      } 

      @Override 
      public Iterator getPrefixes(String val) { 
       throw new IllegalAccessError("Not implemented!"); 
      } 

      @Override 
      public String getPrefix(String uri) { 
       throw new IllegalAccessError("Not implemented!"); 
      } 
     }; 

     XPath xPath = XPathFactory.newInstance().newXPath(); 
     xPath.setNamespaceContext(ctx); 


     Node node = null; 
     try { 
      node = (Node) xPath.evaluate("/n:mynode/n:name", doc, XPathConstants.NODE); 
      System.out.println(node.getNodeName()); 
      System.out.println(node.getFirstChild().getNodeValue()); 
     } catch (Exception e) { 

     } 
    } 
} 

Więc będzie to rozwiązać domyślnej przestrzeni nazw (xmlns) do http://www.example.com gdy węzeł z n prefiksu spotyka.

0

nazw XML jest świadomy. Każdy element XML (i atrybut) ma powiązany obszar nazw; jeśli nie podano inaczej, jest to pusta (domyślna) przestrzeń nazw.

W twoim przypadku jest prawdopodobne, że dokument XML, który próbujesz odczytać, używa przestrzeni nazw, a twoje zapytanie XPath wydaje się sprawdzać tylko emtpy namespace. Dlatego nie otrzymasz wyniku z powrotem. Upewnij się, że używasz właściwej przestrzeni nazw i to zadziała.

+0

Tak. Mój plik XML używa przestrzeni nazw. Ale nie dostałem twojego drugiego punktu. Przepraszam, ale jestem początkującym w kwestii związanych z XPath. Czy możesz wyjaśnić, jak to zrobić? "" Twoje zapytanie XPath wydaje się tylko kwerendy do przestrzeni nazw emtpy, a więc nie otrzymasz wyniku z powrotem. Upewnij się, że używasz właściwej przestrzeni nazw i będzie działać " – Pramod

Powiązane problemy