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());

Вот мой 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>

Вот мой вывод:

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)

Я продолжаю получать эту ошибку. Я полностью потерян. Я понятия не имею, что делать. Я хочу иметь один узел и иметь возможность захватывать все его дочерние элементы и помещать их в массив или список, чтобы я мог их перебирать.

Вот весь мой импорт:

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;

Мне было очень трудно заставить эту Java анализировать этот XML-файл.


person Rob Avery IV    schedule 08.11.2012    source источник
comment
пожалуйста, опубликуйте свой импорт, думаю, вы что-то пропустили там.   -  person Frank    schedule 08.11.2012
comment
Было бы полезно, если бы вы указали, какая строка в вашем фрагменте является строкой 61.   -  person cjstehno    schedule 08.11.2012
comment
К тому же название неправильное. Это не ошибка синтаксического анализа, а исключение приведения класса.   -  person Has QUIT--Anony-Mousse    schedule 08.11.2012


Ответы (3)


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

Узел не Element, а Node.

Попробуй это:

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

Узлы могут быть, например, текстовыми узлами или элементами. Особенно,

<root>
<element/>
</root>

составляет 4 узла. элемент root, текстовый узел, содержащий \n, элемент element и еще один текстовый узел, содержащий \n.

person Has QUIT--Anony-Mousse    schedule 08.11.2012
comment
Я меняю элементы на узлы, но это все равно дает мне неправильный ответ. Вместо исключений будет выведено следующее: 1\ntest-fw:test\n3\n#text - person Rob Avery IV; 08.11.2012
comment
вы знаете, что новые строки будут создавать текстовые узлы между вашими элементами? Ваш первый узел — это новая строка между <rule-tree> и <rule>. Это строка длины 1, содержащая \n. - person Has QUIT--Anony-Mousse; 08.11.2012
comment
Итак, я предполагаю, что когда #text выводится, это \n? - person Rob Avery IV; 09.11.2012
comment
Да, это так. При работе с XML обязательно защитите программу от дополнительных текстовых узлов и дополнительных пробелов. Во многих случаях вы можете захотеть обрабатывать строку, такую ​​как an\n example, так же, как an example, чтобы позволить пользователю вставлять произвольные символы новой строки, чтобы сделать XML более читабельным. Веб-браузеры, например, делают это. - person Has QUIT--Anony-Mousse; 09.11.2012
comment
Что будут делать эти две строки? dbf.setNamespaceAware (истина); dbf.setValidate(dtdValidate || xsdValidate); - person Rob Avery IV; 09.11.2012
comment
Включите осведомленность о пространстве имен и проверку. Возьмите случайную книгу XML, чтобы узнать, что такое пространства имен (теги и атрибуты, начинающиеся с something:, используют пространства имен), и проверка, ну, в общем, сообщит об ошибках, когда файл не является допустимым XML. - person Has QUIT--Anony-Mousse; 09.11.2012
comment
Есть ли простой способ удалить эти #test из NodeList? - person Rob Avery IV; 09.11.2012

Обратите внимание, что NodeList.item возвращает объект Node, который может, но не обязательно, быть Element.

В вашем случае метод возвращает DeferredTextImpl экземпляр, представляющий текстовый узел. Этот класс реализует DeferredNode интерфейс, который, в свою очередь, является субинтерфейсом Node.

Чтобы обработать экземпляры Node, вам нужно убедиться, что вы можете безопасно выполнять приведение типов. Интерфейс Node предоставляет методы, позволяющие проверить тип узла getNodeType, который возвращает значение short, которое можно сравнить с константами, определенными в том же интерфейсе, например ELEMENT_NODE

person toniedzwiedz    schedule 08.11.2012
comment
Что будут делать эти две строки? dbf.setNamespaceAware (истина); dbf.setValidate(dtdValidate || xsdValidate); - person Rob Avery IV; 09.11.2012
comment
Первый (dbf.setNamespaceAware(true);) заставляет синтаксический анализатор учитывать пространства имен XML. Проще говоря, пространства имен позволяют различать элементы с одинаковыми именами и разными определениями. Элемент cat может означать совершенно разные вещи в документе, описывающем животных, и в документе, посвященном командам оболочки. Благодаря пространствам имен каждый может определять свои собственные элементы, структурировать их и называть по своему усмотрению. - person toniedzwiedz; 09.11.2012
comment
Что касается второго (dbf.setValidating(dtdValidate || xsdValidate);), то в документы XML можно встроить определения типа документа. Если такое определение предоставлено, можно не только проверить, является ли документ правильным форматом но также следует определенной схеме. Установка для свойства validating значения true заставляет синтаксический анализатор проверять соответствие встроенному DTD (если он есть), а не только корректность. - person toniedzwiedz; 09.11.2012

Просто нужно проверить Nodeявляется ли Element или нет. Ниже приведен способ преобразования Node в 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);
         ............................
    }
}
person Harmeet Singh Taara    schedule 19.05.2013