2013-05-17 22 views
8

Đây là XML đầu vào:Không thể đọc xml với tiền tố namespace sử dụng DOM phân tích cú pháp

<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> 

này mã mà tôi đang sử dụng để đọc XML (xmlString Biến chứa XML ở trên):

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)); 

Output:

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

tôi có thể đọc phần tử nếu tôi sử dụng "ns2: token" là tên thẻ, nhưng tôi không muốn sử dụng thứ tiền tố điện tử trong mã của tôi vì tôi không chắc chắn rằng nó sẽ giống nhau hay thay đổi trong tương lai. Có cách nào để đọc phần tử xml mà không cần mã hóa cứng không gian tên trong tên thẻ không?

Trả lời

8

Phương pháp W3C dom cho các yếu tố namespaced:

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 trước phiên bản của W3C DOM được sự ủng hộ nghèo cho không gian tên vì vậy tôi không sử dụng nó. Tuy nhiên, nếu bạn sử dụng ở trên với không gian tên đầy đủ, thì ANI http://schemas.xmlsoap.org/soap/envelope/ nó sẽ hoạt động. Tiền tố là không quan trọng - nó không có sự vĩnh cửu bên ngoài tài liệu nó được sử dụng trong

vì vậy hãy thử:

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

Bạn luôn có thể gán không gian tên cho một biến, điều này sẽ cho phép thay đổi nó khi đang di chuyển trong tương lai.

0

Cố gắng sử dụng biểu thức XPath.. Xem mã mẫu bên dưới.

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

được namespace first

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

sau đó sử dụng biến namespace accrodingly

ví dụ:

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

Có lẽ một hack, nhưng giải quyết vấn đề của tôi như một say mê :) – Tarmo

Các vấn đề liên quan