2012-11-08 18 views
6

Đây là mã của tôi: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()); 

Đây là tập tin XML của tôi:

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

Dưới đây là kết quả của tôi:

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) 

tôi tiếp tục nhận được lỗi này . Tôi hoàn toàn lạc mất. Tôi không có ý tưởng gì để làm. Tôi muốn có thể có một nút, và có thể lấy tất cả các con của nó và đặt chúng vào một mảng hoặc danh sách, vì vậy tôi có thể lặp qua chúng.

Dưới đây là tất cả các hàng nhập khẩu của tôi:

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; 

Tôi đã có thời gian khó khăn nhất cố gắng để có được Java này để phân tích tập tin XML này.

+0

vui lòng đăng nhập của bạn, nghĩ rằng bạn đã bỏ lỡ điều gì đó ở đó. – Frank

+0

Dòng nào là dòng 61? –

+0

Sẽ hữu ích nếu bạn chỉ ra dòng nào trong đoạn mã của bạn là dòng 61. – cjstehno

Trả lời

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

Nút không phải là Element, nhưng là Node.

Hãy thử điều này:

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

Nodes có thể các nút văn bản hoặc các yếu tố, ví dụ. Cụ thể,

<root> 
<element/> 
</root> 

là nút. Một rootyếu tố, một nút văn bản chứa \n, các elementyếu tố và một nút văn bản chứa \n.

+0

Tôi đổi Element thành Nodes, nhưng nó vẫn cho tôi câu trả lời sai. Thay vào đó, các ngoại lệ, nó sẽ xuất ra điều này: 1 \ ntest-fw: test \ n3 \ n # text –

+0

bạn biết rằng các dòng mới sẽ tạo ra các nút văn bản giữa các phần tử của bạn? Nút đầu tiên của bạn là ** newline ** inbetween của '' và ''. Đó là một chuỗi có độ dài 1, chứa '\ n'. –

+0

Vì vậy, tôi đoán rằng khi kết quả #text, đó là \ n? –

3

Lưu ý rằng NodeList.item trả về đối tượng Node, có thể nhưng không nhất thiết phải là Element.

Trong trường hợp của bạn, phương thức trả về phiên bản DeferredTextImpl, thể hiện một nút văn bản. Lớp này triển khai giao diện DeferredNode, lần lượt là giao diện con của Node.

Để xử lý các trường hợp Node, bạn sẽ phải đảm bảo bạn có thể thực hiện an toàn dàn diễn viên. Giao diện Node cung cấp phương pháp cho phép bạn kiểm tra kiểu của một node getNodeType, mà trả về một giá trị short mà bạn có thể so sánh với các hằng số được định nghĩa trong giao diện rất giống như ELEMENT_NODE

+0

Hai dòng này sẽ làm gì? dbf.setNamespaceAware (true); dbf.setValidating (dtdValidate || xsdValidate); –

+0

Phần đầu tiên ('dbf.setNamespaceAware (true);') làm cho trình phân tích cú pháp xem xét [XML namespaces] (http://en.wikipedia.org/wiki/XML_namespace). Nói một cách đơn giản, các không gian tên cho phép bạn phân biệt các phần tử với cùng tên và các định nghĩa khác nhau. Một phần tử 'cat' có thể có nghĩa là những thứ hoàn toàn khác nhau trong một tài liệu mô tả động vật và trong một tài liệu về các lệnh shell. Nhờ không gian tên, mọi người có thể xác định các yếu tố, cấu trúc của riêng mình và đặt tên cho chúng theo ý muốn của chúng. – toniedzwiedz

+0

Đối với phiên bản thứ hai ('dbf.setValidating (dtdValidate || xsdValidate);'), có thể nhúng [Định nghĩa kiểu tài liệu] (http://en.wikipedia.org/wiki/Document_Type_Definition) vào tài liệu XML. Nếu định nghĩa như vậy được cung cấp, có thể không chỉ kiểm tra xem tài liệu có được [hình thành tốt] hay không (http://en.wikipedia.org/wiki/Well-formed_element) mà còn theo một lược đồ cụ thể. Việc đặt thuộc tính 'validating' thành' true' làm cho trình phân tích cú pháp kiểm tra sự tuân thủ với một DTD được nhúng (nếu có) và không chỉ cho tính đúng đắn. – toniedzwiedz

4

Chỉ cần kiểm tra Node là một Element hay không . Sau đây là cách để chuyển đổi Node thành 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); 
     ............................ 
    } 
}