2017-02-12 89 views
-2

我正面臨着訪問XML值的困難,任何人都可以讓我知道我在想什麼。Java XML解析問題

String xml = "<Standard p1:oid=\"00000000-0000-0000-0000-000000f674c1\"\n" + 
       "        xmlns:p1=\"com.iMelt.metaCore.DataObjects.Core\" xmlns=\"com.iMelt.Car.Model.Core\"\n" + 
       "        reasonCode=\"0\">\n" + 
       " <p1:__info p1:eid=\"00000000-0000-0000-0000-000000000000\">\n" + 
       "  <p1:creationDate>2016-05-28T20:33:45.337+00:00</p1:creationDate>\n" + 
       "  <p1:lastEditorRef>Administrator</p1:lastEditorRef>\n" + 
       "  <p1:version>5</p1:version>\n" + 
       " </p1:__info>\n" + 
       " <ChangeState>Approved</ChangeState></Standard>"; 

byte[] byteArray = xml.getBytes(); 
ByteArrayInputStream inputStream = new ByteArrayInputStream(byteArray); 
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
factory.setNamespaceAware(true); 
DocumentBuilder builder = factory.newDocumentBuilder(); 
Document doc = builder.parse(inputStream); 
XPathFactory xpathfactory = XPathFactory.newInstance(); 
XPath xpath = xpathfactory.newXPath(); 
XPathExpression expr = xpath.compile("/Standard/ChangeState"); 
Object result = expr.evaluate(doc, XPathConstants.NODESET); 
+1

你面對什麼樣的困難?確切的問題是什麼! –

+0

我也嘗試過/ ChangeState,並沒有在結果中填充「Approved」值 – developer

+0

您的XML缺少XML減速度<?xml version =「1.0」encoding =「UTF-8」?>' –

回答

2

的問題是,是,你不必節點被稱爲「標準」和「改變狀態」,你已經命名空間標準和改變狀態的版本節點。

因此,您需要使用XPath.setNamespace()方法將前綴與命名空間相關聯,然後在xpath表達式中使用該前綴。注意:因爲你只使用在查詢默認的命名空間,這就是你必須指定,像

String xml = "<Standard p1:oid=\"00000000-0000-0000-0000-000000f674c1\"\n" 
      + "        xmlns:p1=\"com.iMelt.metaCore.DataObjects.Core\" xmlns=\"com.iMelt.Car.Model.Core\"\n" 
      + "        reasonCode=\"0\">\n" + " <p1:__info p1:eid=\"00000000-0000-0000-0000-000000000000\">\n" 
      + "  <p1:creationDate>2016-05-28T20:33:45.337+00:00</p1:creationDate>\n" + "  <p1:lastEditorRef>Administrator</p1:lastEditorRef>\n" 
      + "  <p1:version>5</p1:version>\n" + " </p1:__info>\n" + " <ChangeState>Approved</ChangeState></Standard>"; 

    byte[] byteArray = xml.getBytes(); 
    ByteArrayInputStream inputStream = new ByteArrayInputStream(byteArray); 
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
    factory.setNamespaceAware(true); 
    DocumentBuilder builder = factory.newDocumentBuilder(); 
    Document doc = builder.parse(inputStream); 
    XPathFactory xpathfactory = XPathFactory.newInstance(); 
    XPath xpath = xpathfactory.newXPath(); 
    xpath.setNamespaceContext(new NamespaceContext() { 

     @Override 
     public String getNamespaceURI(String prefix) { 
      return "com.iMelt.Car.Model.Core"; 
     } 

     @Override 
     public String getPrefix(String namespaceURI) { 

      return "x"; 
     } 

     @Override 
     public Iterator getPrefixes(String namespaceURI) { 
      return null; 
     } 

    }); 
    XPathExpression expr = xpath.compile("/x:Standard/x:ChangeState"); 
    NodeList result = (NodeList) expr.evaluate(doc, XPathConstants.NODESET); 

的其他不太有效的選項是去除聲明

factory.setNamespaceAware(true); 
+0

我已經嘗試了兩個選項xpath.setNamespaceContext並刪除factory.setNamespaceAware(true),但也沒有幫助 – developer

+0

抱歉,但這是按原樣工作,您是否更改xpath表達式 - 添加前綴'x'? – MeBigFatGuy

+0

是的,它的工作,非常感謝。 – developer

0

下面的代碼輸出「批准」。我已經刪除了factory.setNamespaceAware(true);,以便您不需要指定默認名稱空間並在末尾添加代碼以輸出文本值。

import java.util.*; 
import java.lang.*; 
import java.io.*; 
import javax.xml.parsers.*; 
import org.w3c.dom.*; 
import javax.xml.xpath.*; 

// ... 

String xml = "<Standard p1:oid=\"00000000-0000-0000-0000-000000f674c1\"\n" + 
       "        xmlns:p1=\"com.iMelt.metaCore.DataObjects.Core\" xmlns=\"com.iMelt.Car.Model.Core\"\n" + 
       "        reasonCode=\"0\">\n" + 
       " <p1:__info p1:eid=\"00000000-0000-0000-0000-000000000000\">\n" + 
       "  <p1:creationDate>2016-05-28T20:33:45.337+00:00</p1:creationDate>\n" + 
       "  <p1:lastEditorRef>Administrator</p1:lastEditorRef>\n" + 
       "  <p1:version>5</p1:version>\n" + 
       " </p1:__info>\n" + 
       " <ChangeState>Approved</ChangeState></Standard>"; 

byte[] byteArray = xml.getBytes(); 
ByteArrayInputStream inputStream = new ByteArrayInputStream(byteArray); 
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
DocumentBuilder builder = factory.newDocumentBuilder(); 
Document doc = builder.parse(inputStream); 
XPathFactory xpathfactory = XPathFactory.newInstance(); 
XPath xpath = xpathfactory.newXPath(); 
XPathExpression expr = xpath.compile("/Standard/ChangeState"); 
NodeList result = (NodeList)expr.evaluate(doc, XPathConstants.NODESET); 
Node node = result.item(0); 
System.out.println(node.getTextContent()); 
+0

我已經在上面嘗試過了,它給出空指針異常 – developer

+0

您可以在這裏看到它運行時沒有錯誤並輸出「已批准」:https://ideone.com/JGMiag – NineBerry