2013-05-17 32 views
8

To XML wejściowe:Nie można odczytać XML z użyciem przedrostka przestrzeni nazw DOM parser

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> 
    <SOAP-ENV:Header/> 
    <SOAP-ENV:Body> 
     <ns2:SendResponse xmlns:ns2="http://mycompany.com/schema/"> 
     <ns2:SendResult> 
      <ns2:Token>A00179-02</ns2:Token> 
     </ns2:SendResult> 
     </ns2:SendResponse> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope> 

ten kod, który używam do zapoznania się z XML (Variable xmlString zawiera XML powyżej):

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
dbf.setNamespaceAware(true); 
DocumentBuilder db = dbf.newDocumentBuilder(); 
InputSource is = new InputSource(); 
is.setCharacterStream(new StringReader(xmlString)); 
Document doc = db.parse(is); 

System.out.println("Element :" + doc.getElementsByTagName("Token").item(0)); 
System.out.println("Element :" + doc.getElementsByTagName("ns2:Token").item(0)); 

wyjściowa:

Element :null 
Element :[ns2:Token: null] 

jestem w stanie odczytać element, jeśli mogę użyć „NS2: Token” jako nazwę znacznika, ale nie chcę używać th Prefiks e w moim kodzie, ponieważ nie jestem pewien, czy to będzie to samo, czy zmiana w przyszłości. Czy jest jakiś sposób, aby odczytać element xml bez twardego kodowania przestrzeni nazw w nazwie znacznika?

Odpowiedz

8

Sposób W3C dom dla przestrzeni nazw elementów:

getElementsByTagNameNS 

NodeList getElementsByTagNameNS(String namespaceURI, 
           String localName) 

    Returns a NodeList of all the Elements with a given local name and namespace URI in document order. 

    Parameters: 
     namespaceURI - The namespace URI of the elements to match on. The special value "*" matches all namespaces. 
     localName - The local name of the elements to match on. The special value "*" matches all local names. 
    Returns: 
     A new NodeList object containing all the matched Elements. 
    Since: 
     DOM Level 2 

IIRC wcześniejsza wersja W3C DOM miał słabe wsparcie dla przestrzeni nazw, więc nie należy go używać. Jednak jeśli użyjesz powyższego z pełnym przestrzenią nazwURI http://schemas.xmlsoap.org/soap/envelope/, to powinno działać. Przedrostek ma znaczenia - nie ma trwałość poza dokumentem stosuje się go w

więc spróbuj:

System.out.println("Element :" + doc.getElementsByTagNameNS(
     "http://schemas.xmlsoap.org/soap/envelope/", "Token").item(0)); 
0

Zawsze można przypisać przestrzeń nazw do zmiennej, co pozwoliłoby zmienić ją w locie w przyszłości.

0

spróbuje użyć wyrażenia XPath.. Zobacz przykładowy kod poniżej.

Document doc = dBuilder.parse(new ByteArrayInputStream(responseXML.getBytes())); 
doc.getDocumentElement().normalize(); 
XPath xPath = XPathFactory.newInstance().newXPath(); 

String expression = "/ns6:ReadPersonReturn/ns6:object/ns3:Person/ns3:Phone/ns3:item"; 
NodeList nodes = (NodeList) xPath.compile(expression).evaluate(doc, XPathConstants.NODESET); 
Element secondNode = null; 
if(nodes != null && nodes.getLength() > 0){ 
    secondNode = (Element) leadCloudPingRecordNodes.item(i); 
} 
1

dostać pierwszy

docFactory.setNamespaceAware(true); 
StringBuilder nameSpace = new StringBuilder(
        doc.getDocumentElement().getPrefix() != null ? doc.getDocumentElement().getPrefix() + ":" : ""); 

następnie użyć zmiennej przestrzeni nazw przestrzeni nazw accrodingly

np

Node node= doc.getElementsByTagName(nameSpace + "Node1").item(0) 
        .getFirstChild(); 
+0

Może hack, ale rozwiązuje mój problem jak urok :) – Tarmo

Powiązane problemy