• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

[Java] jdom getDescendants - cast error Text zu Element

No3x

Mitglied
Hallo! Ich bin gerade dabei eine HTML-Datei auszulesen. Eigentlich benötige ich nur den Value eines Textfeldes und dachte, dass ich dafür am besten über das ganze Dokument wander, bis ich beim gewünschten ankomme.
Hier erstmal mein Code:
Code:
  String xml =     "<div>" +
        "<b>blubb</b>" +
        "    <input value='senden' />" +         
        "</div>";          
        SAXBuilder builder = new SAXBuilder();
        Document doc = builder.build(new StringReader(xml));                 
        try {
            Iterator<Element> i = doc.getRootElement().getDescendants();
            while(i.hasNext()) {
                Element currentElement = (Element)i.next();
                System.out.println(currentElement);
                Iterator<Attribute> j = currentElement.getAttributes().iterator();
                while(j.hasNext()) {
                    Attribute currentAttribute = (Attribute)j.next();
                    System.out.println(currentAttribute);
                }
            }
        } catch (Exception e) {
        System.err.println(e.getMessage());
        }
Fehler: org.jdom.Text cannot be cast to org.jdom.Element
Problem ist nun, dass ich nicht weiß wie ich sagen soll, dass er nicht versucht den Text zu iterieren - was er ja wohl scheinbar versucht.
Hat jemand eine Idee?
 
Zuletzt bearbeitet:
Werbung:
Eine Instanz welcher Klasse gibt dir denn i.next() zurück?

Diese Klasse dürfte jedenfalls Informationen zum Node-Type enthalten. Für Textknoten wäre das irgendwas mit „text“. Davon müsstest du abhängig machen, ob du über die Attribute iterierst. Das ergibt bei Textknoten wohl keinen Sinn.
 
Aus der JDom-Doku kann ich folgendes entnehmen:
getDescendants()
Returns an iterator that walks over all descendants in document order.
Code:
Iterator<Element> i = doc.getRootElement().getDescendants();
Also alle Unterelemente (vom Typ Element) unterhalb des root-Elements.

Falls du mich damit auf etwas hinweisen wolltest: ich hab's noch nicht erkannt. :D

Auch so etwas funktioniert nicht:
Code:
Iterator<Node> i = doc.getRootElement().getDescendants();        
            while(i.hasNext()) {
                Node currentElement = (Node)i.next();
                if(currentElement.getNodeType() == Node.TEXT_NODE) {
                    System.out.println("Text erkannt");
                }
                System.out.println(currentElement);
            }
org.jdom.Element cannot be cast to org.w3c.dom.Node

Meine Imports sind
Code:
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.w3c.dom.Node;

Ich bin mir ehrlich gesagt sehr unsicher was ich importieren muss. org.jdom.Element oder org.w3c.dom.Element?
org.w3c.dom.Element bietet .getNodeType(). Jedoch kann ich dann wieder nicht casten. :twisted:
 
Zuletzt bearbeitet:
Werbung:
Hab's mir gerade nur rudimentär zusammengeschustert.

Jedenfalls gibt es auch eine getDescendants-Version mit Filter.

- Element (JDOM v1.1.1)

Als Filter lässt sich dann ein Filter übergeben, der nur Elemente matcht.

Code:
package javatest;

import java.io.StringReader;
import java.util.Iterator;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.filter.ElementFilter;
import org.jdom.input.SAXBuilder;

/**
 *
 * @author marc
 */
public class Main {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
          String xml =     "<div>" +
        "<b>blubb</b>" +
        "    <input value='senden' />" +
        "</div>";
        SAXBuilder builder = new SAXBuilder();

        Document doc = null;

        try {
            doc = builder.build(new StringReader(xml));
        } catch (Exception e ) {
            System.err.println(e.getMessage());
        }

        try {
            Iterator<Element> i = doc.getRootElement().getDescendants(new ElementFilter());
            while(i.hasNext()) {
                Element currentElement = i.next();
                System.out.println(currentElement);
                Iterator<Attribute> j = currentElement.getAttributes().iterator();
                while(j.hasNext()) {
                    Attribute currentAttribute = j.next();
                    System.out.println(currentAttribute);
                }
            }
        } catch (Exception e) {
            System.err.println(e.getMessage());
        }
    }
}

Hilft das schon?

PS: Das Casten solltest du dir dann auch sparen können.
 
Vielen Dank!
Das funktioniert mit diesem vereinfachten Beispiel. Ich werd eso morgen mal in mein Projekt einbauen und schauen b ich dort zum Ergebnis komme.
Aber: Wie soll ich wissen, dass es einen solchen ElementFilter gibt? Wie geht man bei sowas am besten ran? Erstmal die ganze Doku studieren?
 
Das ist nie verkehrt und letztlich wohl ohnehin nicht zu vermeiden, da man sich ja nicht bei jeder Methode denken kann, was der Entwickler genau damit bezweckt. Wenn du eine IDE nutzt, bekommst du beim Tippen über die Autovervollständigung in der Regel auch alternative (überladene) Varianten angezeigt. Außerdem gibt es üblicherweise Shortcuts, um in die Methodendefinitionen zu springen. In NetBeans kannst du etwa Strg drücken und zum Beispiel auf einen Methodennamen klicken, um zur passenden Stelle im Library-Code zu springen.

Ich finde es generell immer recht hilfreich, über Rückgabewerte zu gehen. Die entsprechende Klasse ist in Java ja genau festgelegt. Da kannst du zum Beispiel auch sehen, zu welchem Package ein Klassenname wie Element gehört. (Im Quellcode der Library steht oben eine entsprechende import-Zeile.)

Die Doku ist aber dennoch immer Pflichtprogramm.
 
Werbung:
Zurück
Oben