2009-04-21 11 views
35

के साथ एक्सएमएल नोड टेक्स्ट मान प्राप्त करना मैं Node.getNodeValue(), Node.getFirstChild().getNodeValue() या Node.getTextContent() के साथ टेक्स्ट मान नहीं ला सकता हूं।जावा डोम

मेरे एक्सएमएल तरह

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

है और मैं टैग मूल्य (गैर पाठ तत्व काम करता है ठीक प्राप्त करने में कठिनाई) प्राप्त करने के लिए कोशिश कर रहा हूँ। मेरे जावा कोड लगता है

तरह
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_ 
... 

मदद के लिए धन्यवाद बाहर प्रिंट करता है।

+1

यदि आप स्पष्ट रूप से संकेत देते हैं कि परिवर्तनीय 'एन' वर्तमान में क्या है, दस्तावेज़ या दस्तावेज़ एलिमेंट? – AnthonyWJones

+1

मैंने 'n' घोषणा भाग – Emilio

उत्तर

45

मैं an2.getNodeName() के परिणाम के साथ-साथ डीबगिंग उद्देश्यों के परिणाम भी प्रिंट करूंगा। मेरा अनुमान है कि आपका पेड़ क्रॉलिंग कोड उस नोड्स पर क्रॉल नहीं कर रहा है जो आपको लगता है। यह संदेह आपके कोड में नोड नामों की जांच की कमी से बढ़ाया गया है।

इसके अलावा, नोड के लिए जावाडोक टाइपिंग एलिमेंट के नोड्स के लिए शून्य को वापस करने के लिए "getNodeValue()" को परिभाषित करता है। इसलिए, आपको वास्तव में getTextContent() का उपयोग करना चाहिए। मुझे यकीन नहीं है कि वह आपको वह पाठ क्यों नहीं देगा जो आप चाहते हैं।

शायद आपके टैग नोड के बच्चों को फिर से चालू करें और देखें कि किस प्रकार हैं?

इस कोड की कोशिश की और यह मेरे लिए काम करता है:

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

जोड़ा है, अब मैं भी प्रिंट कर रहा हूं .getNodeName() .. और यह सही मान (टैग) – Emilio

+0

देता है मेरे टैग तत्व में बच्चे नहीं हैं:/यदि मैं केवल 2 के साथ प्रयास करता हूं। getFirstChild()। getTextContent() या इसी तरह यह एक NullPointerException – Emilio

+0

फेंकने के बजाय getChildElements का उपयोग करने का प्रयास करें। फर्स्ट चाइल्ड()। शायद getFirstChild() कुछ कारणों से एलिमेंट टाइप किए गए नोड्स पर छोड़ रहा है? – jsight

17

अपने XML काफी गहरी हो जाता है, तो आप XPath, जो आपके JRE के साथ आता है के उपयोग पर विचार करना चाह सकते हैं , ताकि आप सामग्री का उपयोग अधिक आसानी से कर सकें:

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); 
    } 
} 
+0

दुर्भाग्य से एक शैक्षिक नौकरी है और मुझे डीओएम एपीआईएस का उपयोग करना होगा:/ – Emilio

+0

क्या आप जेडीओएम एपीआई का उपयोग कर सकते हैं? इसके साथ काम करना बहुत आसान है। – jdigital

+0

धन्यवाद, इस पूर्ण उदाहरण (आयात के साथ) वास्तव में अन्य समान समाधानों के साथ संघर्ष करने के बाद मुझे मदद मिली। –

1

मैं एक बहुत पुराना जावा का उपयोग करता हूं। जेडीके 1.4.08 और मुझे एक ही समस्या थी। मेरे लिए Node कक्षा में getTextContent() विधि नहीं थी। नोड के मूल्य को प्राप्त करने के लिए मुझे Node.getNodeValue() के बजाय Node.getFirstChild().getNodeValue() का उपयोग करना पड़ा। यह मेरे लिए तय है।

1

यदि आप vtd-xml पर खुले हैं, जो performance and memory efficiency दोनों पर उत्कृष्ट है, तो नीचे जो कुछ आप ढूंढ रहे हैं उसे करने के लिए कोड है ... 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)); 
     } 
    } 
} 
संबंधित मुद्दे