2012-11-08 16 views
6

Oto mój kod:Java XML: ClassCastException 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()); 

Oto mój plik XML:

<?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> 

Oto moje wyjście:

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) 

Wciąż otrzymuję ten błąd . Jestem całkowicie zagubiony. Nie mam pojęcia, co robić. Chcę móc mieć jeden węzeł i móc pobrać wszystkie jego dzieci i umieścić je w tablicy lub liście, dzięki czemu mogę je przeglądać.

Oto wszystkie moje import:

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; 

miałem najtrudniejszy czas próbuje uzyskać ten Java do analizowania tego pliku XML.

+0

proszę zaksięgować import, wydaje się, że coś tam zostało. – Frank

+0

Która linia to linia 61? –

+0

Byłoby pomocne, gdybyś wskazał, który wiersz w twoim fragmencie to linia 61. – cjstehno

Odpowiedz

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

Węzeł nie jest Element, ale Node.

Spróbuj tego:

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

Węzły mogą być węzły tekstowe lub elementy, na przykład. W szczególności

<root> 
<element/> 
</root> 

jest węzłów. rootelementem węzeł tekst zawierający \n The elementelementem i inny węzeł tekst zawierający \n.

+0

Zmieniam elementy na węzły, ale wciąż daje mi złą odpowiedź. Zamiast tego Wyjątki wyprowadzą to: 1 \ ntest-fw: test \ n3 \ n # text –

+0

Czy wiesz, że nowe linie będą tworzyć węzły tekstowe pomiędzy Twoimi elementami? Twój pierwszy węzeł to ** nowa linia ** pomiędzy "" i "". Który jest ciągiem o długości 1, zawierającym '\ n'. –

+0

Zgaduję więc, że gdy wyjście #text, to jest \ n? –

3

Należy zauważyć, że NodeList.item zwraca obiekt Node, który może ale nie musi być Element.

W twoim przypadku metoda zwraca instancję DeferredTextImpl, która reprezentuje węzeł tekstowy. Ta klasa implementuje interfejs DeferredNode, który z kolei stanowi podinterfejs Node.

Aby przetwarzać instancje Node, należy upewnić się, że można bezpiecznie wykonać rzutowanie. Interfejs Node dostarcza metody, które pozwalają sprawdzić typ węzła getNodeType, która zwraca wartość short, które można porównać do stałych zdefiniowanych w tym samym interfejsie jak ELEMENT_NODE

+0

Co by zrobiły te dwie linie? dbf.setNamespaceAware (true); dbf.setValidating (dtdValidate || xsdValidate); –

+0

Pierwsza ('dbf.setNamespaceAware (true);) sprawia, że ​​analizator uwzględnia [przestrzenie nazw XML] (http://en.wikipedia.org/wiki/XML_namespace). Mówiąc prościej, przestrzenie nazw umożliwiają rozróżnienie elementów o tych samych nazwach i różnych definicjach. Element 'cat' może oznaczać zupełnie różne rzeczy w dokumencie opisującym zwierzęta oraz w dokumencie dotyczącym poleceń powłoki. Dzięki przestrzeniom nazw każdy może zdefiniować własne elementy, strukturę i nazwać je według własnego uznania. – toniedzwiedz

+0

Jeśli chodzi o drugi ('dbf.setValidating (dtdValidate || xsdValidate);)), możliwe jest osadzenie [definicji typu dokumentu] (http://en.wikipedia.org/wiki/Document_Type_Definition) w dokumentach XML. Jeśli taka definicja zostanie dostarczona, możliwe jest nie tylko sprawdzenie, czy dokument jest [dobrze sformułowany] (http://en.wikipedia.org/wiki/Well-formed_element), ale także podąża za określonym schematem. Ustawienie właściwości 'validating' na' true' powoduje, że analizator sprawdza zgodność z osadzonym DTD (jeśli jest obecny), a nie tylko dla poprawności formułowania. – toniedzwiedz

4

wystarczy sprawdzić Node jest Element albo nie . Poniżej znajduje się sposób przekonwertowania Node na Element.

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); 
     ............................ 
    } 
} 
Powiązane problemy