2017-03-02 147 views
4

我加載某些XML字符串是這樣的:爲什麼getLocalName()返回null?

Document doc = getDocumentBuilder().parse(new InputSource(new StringReader(xml))); 

後來,我提取節點從這個Document

XPath xpath = getXPathFactory().newXPath(); 
XPathExpression expr = xpath.compile(expressionXPATH); 
NodeList nodeList = (NodeList)expr.evaluate(doc, XPathConstants.NODESET); 

Node node = nodeList.item(0); 

現在我想要得到這個節點的本地名字,但我得到null

node.getLocalName(); // return null 

與調試,我看到我的節點有以下類型:DOCUMENT_POSITION_DISCONNECTED

The Javadoc指出,對於這種類型的節點getLocalName()回報null

  • 爲何節點類型DOCUMENT_POSITION_DISCONNECTED,而不是ELEMENT_NODE?
  • 如何「轉換」節點的類型?
+1

如何顯示一個最小但完整的樣本來讓我們重現問題?向我們展示'xml'和'expressionXPATH'。 –

+0

你有沒有使用名稱空間感知'DocumentBuilderFactory'? –

+0

至少,顯示您正在使用的XPath表達式。 – VGR

回答

3

如文檔https://docs.oracle.com/javase/7/docs/api/org/w3c/dom/Node.html#getLocalName()狀態:

與一個DOM 1級方法創建的節點,[...]這始終是空

所以一定要確保你使用一個命名空間瞭解DocumentBuilderFactorysetNamespaceAware(true),這樣DOM支持名稱空間感知DOM Level 2/3,並且對於getLocalName()將具有非空值。

一個簡單的測試程序

String xml = "<root/>"; 

    DocumentBuilderFactory db = DocumentBuilderFactory.newInstance(); 

    Document dom1 = db.newDocumentBuilder().parse(new InputSource(new StringReader(xml))); 

    System.out.println(dom1.getDocumentElement().getLocalName() == null); 

    db.setNamespaceAware(true); 

    Document dom2 = db.newDocumentBuilder().parse(new InputSource(new StringReader(xml))); 

    System.out.println(dom2.getDocumentElement().getLocalName() == null); 

輸出

true 
false 

如此(至少),你必須通過使用DOM 1級引起了當地名稱問題,而不是名稱空間感知的文件(生成器工廠)。

+0

如何知道正在使用哪個DOM級別? – Stephan

+0

如果您想查詢現有的實現,您需要查看https://docs.oracle.com/javase/7/docs/api/org/w3c/dom/DOMImplementation.html#hasFeature(java.lang.String ,%20java.lang.String)來測試各種支持的功能。但我不完全確定這是多麼的精確,我只知道對於有意義的XPath,使用名稱空間感知的DOM是必不可少的。 –