2017-02-12 83 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