2012-11-08 3 views
6

Hier ist mein Code:Java XML: Classcast DeferredTextImpl

// get the factory 
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 

try { 

    // Using factory get an instance of document builder 
DocumentBuilder db = dbf.newDocumentBuilder(); 

// parse using builder to get DOM representation of the XML file 
    dom = db.parse(file); 

} catch (ParserConfigurationException pce) { 
    pce.printStackTrace(); 
} catch (SAXException se) { 
    se.printStackTrace(); 
} catch (IOException ioe) { 
    ioe.printStackTrace(); 
} 

NodeList n1 = dom.getChildNodes(); 
Element e1 = (Element) n1.item(0); 

System.out.println(n1.getLength()); 
System.out.println(e1.getNodeName()); 

NodeList n2 = n1.item(0).getChildNodes(); 
Element e2 = (Element) n2.item(0); //Line 61 

System.out.println(n2.getLength()); 
System.out.println(e2.getNodeName()); 

Hier ist meine XML-Datei:

1 
test-fw:test 
Exception in thread "main" java.lang.ClassCastException: com.sun.org.apache.xerces.internal.dom.DeferredTextImpl cannot be cast to org.w3c.dom.Element 
    at testpack.Main.run(Main.java:61) 
    at testpack.Main.main(Main.java:86) 

Ich erhalte diese Fehlermeldung:

<?xml version="1.0" encoding="utf-8"?> 

<test-fw:test 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:test-fw="http://simitar/test-fw"> 

<rule-tree> 
<rule class="matchlines"> 
<property name="contiguous"> true</property> 
<property name="inOrder">false</property> 
<property name="exact">false</property> 
<property name="lines">modelInstantiated</property> 
</rule> 
<rule class="matchlines"> 
<property name="contiguous"> true</property> 
<property name="inOrder">true</property> 
<property name="exact">false</property> 
<property name="lines">InitEvent</property> 
</rule> 
</rule-tree> 

</test-fw:test> 

Hier ist mein Ausgang . Ich bin völlig verloren. Ich habe keine Ahnung, was ich tun soll. Ich möchte in der Lage sein, einen Knoten zu haben, und in der Lage sein, alle seine Kinder zu ergreifen und sie in ein Array oder eine Liste zu setzen, so dass ich sie durchlaufen kann.

Hier sind alle meine Importe:

import java.io.File; 
import java.io.IOException; 
import java.util.List; 
import java.util.Stack; 

import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.parsers.ParserConfigurationException; 

import org.w3c.dom.Document; 
import org.w3c.dom.Element; 
import org.w3c.dom.NodeList; 
import org.xml.sax.SAXException; 

ich die härteste Zeit hatte versucht, diese Java zu bekommen diese XML-Datei zu analysieren.

+0

bitte posten Sie Ihre Importe, denke, dass Sie etwas verpasst haben. – Frank

+0

Welche Linie ist Linie 61? –

+0

Es wäre hilfreich, wenn Sie darauf hingewiesen, welche Zeile in Ihrem Schnipsel Zeile 61 ist. – cjstehno

Antwort

10
NodeList n1 = dom.getChildNodes(); 
Element e1 = (Element) n1.item(0); 

Der Knoten ist kein Element, sondern ein Node.

Try this:

Node no1 = (Node) n1.item(0); 

Knoten können Textknoten oder Elemente sein, zum Beispiel. Insbesondere

<root> 
<element/> 
</root> 

ist Knoten. A root Element, ein Textnode\n enthält, wobei das element Element und eine andere Textnode enthält \n.

+0

Ich ändere die Elemente in Knoten, aber es gibt immer noch die falsche Antwort. Von den Ausnahmen wird stattdessen Folgendes ausgegeben: 1 \ ntest-fw: test \ n3 \ n # text –

+0

Ihnen ist bekannt, dass Zeilenumbrüche Textknoten zwischen Ihren Elementen erzeugen werden? Ihr erster Knoten ist der ** Newline ** zwischen "" und "". Das ist eine Zeichenfolge der Länge 1, die '\ n' enthält. –

+0

Also ich vermute, dass, wenn die # Textausgaben, das ist die \ n? –

3

Beachten Sie, dass NodeList.item ein Objekt Node zurückgibt, das eine Element sein kann, aber nicht sein muss. In Ihrem Fall gibt die Methode eine Instanz zurück, die einen Textknoten darstellt. Diese Klasse implementiert die Schnittstelle DeferredNode, die wiederum eine Subschnittstelle von Node ist.

Um die Node Instanzen zu bearbeiten, müssen Sie sicherstellen, dass Sie den Cast sicher durchführen können. Die Node Schnittstelle bietet Methoden, mit denen Sie den Typ eines Knotens getNodeType, um zu überprüfen, die einen short Wert zurückgibt, die Sie in der gleichen Schnittstelle wie ELEMENT_NODE

+0

Was würden diese beiden Linien tun? dbf.setNamespaceAware (true); dbf.setValidating (dtdValidate || xsdValidate); –

+0

Der erste Eintrag ('dbf.setNamespaceAware (true);') bewirkt, dass der Parser [XML namespaces] (http://en.wikipedia.org/wiki/XML_namespace) berücksichtigt. Namespaces ermöglichen es Ihnen, Elemente mit denselben Namen und unterschiedlichen Definitionen zu unterscheiden. Ein "Katze" -Element kann in einem Dokument, das Tiere beschreibt, und in einem Dokument über Shell-Befehle völlig unterschiedliche Dinge bedeuten. Dank Namespaces kann jeder seine eigenen Elemente definieren, strukturieren und nach Belieben benennen. – toniedzwiedz

+0

Wie beim zweiten ('dbf.setValidating (dtdValidate || xsdValidate);') ist es möglich, [Document Type Definitions] (http://en.wikipedia.org/wiki/Document_Type_Definition) in XML-Dokumente einzubetten. Wenn eine solche Definition bereitgestellt wird, ist es möglich, nicht nur zu überprüfen, ob ein Dokument [wohlgeformt] ist (http://en.wikipedia.org/wiki/Well-formed_element), sondern auch einem bestimmten Schema zu folgen. Wenn die Eigenschaft 'validating' auf' true' gesetzt wird, prüft der Parser, ob er einer eingebetteten DTD (falls vorhanden) entspricht und nicht nur für Wohlgeformtheit. – toniedzwiedz

4

Nur müssen die Node überprüfen definiert die Konstanten vergleichen kann, ist ein Element oder nicht . Im Folgenden finden Sie die Möglichkeit, Node in Element umzuwandeln.

NodeList nodes = root.getChildNodes(); 
for (int i = 0; i < nodes.getLength(); i++) { 
    if(nodes.item(i).getNodeType() == Node.ELEMENT_NODE){ 
     Element element = (Element) nodes.item(i); 
     ............................ 
    } 
}