使用Java DOM获取XML节点文本值

我无法使用Node.getNodeValue()Node.getFirstChild().getNodeValue()Node.getFirstChild().getNodeValue()Node.getFirstChild().getNodeValue()获取文本值。

我的XML就像

 <add job="351"> <tag>foobar</tag> <tag>foobar2</tag> </add> 

而我试图获得标签值(非文本元素获取工作正常)。 我的Java代码听起来像

 Document doc = db.parse(new File(args[0])); Node n = doc.getFirstChild(); NodeList nl = n.getChildNodes(); Node an,an2; for (int i=0; i < nl.getLength(); i++) { an = nl.item(i); if(an.getNodeType()==Node.ELEMENT_NODE) { NodeList nl2 = an.getChildNodes(); for(int i2=0; i2<nl2.getLength(); i2++) { an2 = nl2.item(i2); // DEBUG PRINTS System.out.println(an2.getNodeName() + ": type (" + an2.getNodeType() + "):"); if(an2.hasChildNodes()) System.out.println(an2.getFirstChild().getTextContent()); if(an2.hasChildNodes()) System.out.println(an2.getFirstChild().getNodeValue()); System.out.println(an2.getTextContent()); System.out.println(an2.getNodeValue()); } } } 

它打印出来

 tag type (1): tag1 tag1 tag1 null #text type (3): _blank line_ _blank line_ ... 

谢谢您的帮助。

为了debugging的目的,我也会打印出an2.getNodeName()的结果。 我的猜测是你的树爬行代码没有爬到你认为的节点上。 由于缺less对代码中节点名称的检查,这种怀疑被加强了。

除此之外,Node的javadoc定义了“ getNodeValue ()”为Elementtypes的节点返回null。 因此,你真的应该使用getTextContent()。 我不知道为什么这不会给你你想要的文字。

也许迭代你的标签节点的子节点,看看有哪些types?

试过这个代码,它适用于我:

 String xml = "<add job=\"351\">\n" + " <tag>foobar</tag>\n" + " <tag>foobar2</tag>\n" + "</add>"; DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); ByteArrayInputStream bis = new ByteArrayInputStream(xml.getBytes()); Document doc = db.parse(bis); Node n = doc.getFirstChild(); NodeList nl = n.getChildNodes(); Node an,an2; for (int i=0; i < nl.getLength(); i++) { an = nl.item(i); if(an.getNodeType()==Node.ELEMENT_NODE) { NodeList nl2 = an.getChildNodes(); for(int i2=0; i2<nl2.getLength(); i2++) { an2 = nl2.item(i2); // DEBUG PRINTS System.out.println(an2.getNodeName() + ": type (" + an2.getNodeType() + "):"); if(an2.hasChildNodes()) System.out.println(an2.getFirstChild().getTextContent()); if(an2.hasChildNodes()) System.out.println(an2.getFirstChild().getNodeValue()); System.out.println(an2.getTextContent()); System.out.println(an2.getNodeValue()); } } } 

输出是:

 #text: type (3): foobar foobar #text: type (3): foobar2 foobar2 

如果您的XML相当深入,您可能需要考虑使用JRE附带的XPath,以便您可以更轻松地访问内容:

 String text = xp.evaluate("//add[@job='351']/tag[position()=1]/text()", document.getDocumentElement()); 

完整的例子:

 import static org.junit.Assert.assertEquals; import java.io.StringReader; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathFactory; import org.junit.Before; import org.junit.Test; import org.w3c.dom.Document; import org.xml.sax.InputSource; public class XPathTest { private Document document; @Before public void setup() throws Exception { String xml = "<add job=\"351\"><tag>foobar</tag><tag>foobar2</tag></add>"; DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); document = db.parse(new InputSource(new StringReader(xml))); } @Test public void testXPath() throws Exception { XPathFactory xpf = XPathFactory.newInstance(); XPath xp = xpf.newXPath(); String text = xp.evaluate("//add[@job='351']/tag[position()=1]/text()", document.getDocumentElement()); assertEquals("foobar", text); } } 

我使用一个非常古老的Java。 JDK 1.4.08和我有同样的问题。 我的Node类没有getTextContent()方法。 我不得不使用Node.getFirstChild().getNodeValue()而不是Node.getFirstChild().getNodeValue() Node.getNodeValue()来获取节点的值。 这为我固定。

如果你打开vtd-xml ,它在性能和内存效率方面都很出色 ,下面是在XPath和手动导航中执行你要查找的代码…整个代码非常简洁和简单了解…

 import com.ximpleware.*; public class queryText { public static void main(String[] s) throws VTDException{ VTDGen vg = new VTDGen(); if (!vg.parseFile("input.xml", true)) return; VTDNav vn = vg.getNav(); AutoPilot ap = new AutoPilot(vn); // first manually navigate if(vn.toElement(VTDNav.FC,"tag")){ int i= vn.getText(); if (i!=-1){ System.out.println("text ===>"+vn.toString(i)); } if (vn.toElement(VTDNav.NS,"tag")){ i=vn.getText(); System.out.println("text ===>"+vn.toString(i)); } } // second version use XPath ap.selectXPath("/add/tag/text()"); int i=0; while((i=ap.evalXPath())!= -1){ System.out.println("text node ====>"+vn.toString(i)); } } }