JAXB - flexibles Mappen von Elementen

DevDomi

Mitglied
Abend :),

ich bin neu in der Java Entwicklung und beschäftige mich gerade mit dem parsen von XML Dateien. Ich möchte nun XmlElemente flexible mappen. Also z.B. das sich der Name zwischen XmlElement und der Eigenschaft des Objekts unterscheidet, oder das sich das XmlElement tiefer im Tree befindet und ich nicht die ganze Struktur in Pojos abbilden möchte.
Verschiedene Namen waren schnell gelöst, aber bei Unterschieden in der Struktur komme ich nicht weiter....
Ich hatte dazu gelesen das man dafür am besten @XmlPath nutzt, aber leider klappt dies bei mir nicht. Es findet den Wert dann nicht.

Ich habe folgende XML Datei:
Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<test>
    <customer_i id="100">
      <age_i>29</age_i>
      <name_i>dom</name_i>
    </customer_i>
</test>

Hier ist meine Pojo dazu:
Code:
@XmlRootElement(name = "test")
@XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
    @XmlPath("customer_i/name_i/text()")
    String name;
    @XmlPath("customer_i/age_i/text()")
    int age;
    @XmlAttribute
    int id;
}


Weis hier jemand Rat? Bin ich überhaupt auf dem richtigen Weg?
 

Flown

Administrator
Mitarbeiter
Also der XML Mapping Weg wäre, wenn du die XML Struktur genau so abbilden würdest mit Pojo wie im File. Dann klappt das reibungslos mit De-/Serialiserung. @XmlPath ist jetzt keine standard Annotation im JAXB Kontext.

Aber wenn du wirklcih dabei Hilfe brauchst: der richtige XPath wäre: /test/customer_i/age_i/text() oder //customer_i/age_i/text()
 

DevDomi

Mitglied
Erst einmal danke für die Hilfe :)
Habe jetzt die gesamten Pojos angelegt.
Leider bin ich auf ein weiteres Problem gestoßen, als ich weiter vorangeschritten bin.
Ich habe folgende Struktur:
Code:
<item>
    <title>US-Strategie für Afghanistan: Trump bricht Verhandlungen mit Taliban ab</title>
    <link>https://www.spiegel.de/politik/ausland/donald-trump-bricht-friedensverhandlungen-mit-taliban-ab-a-1285764.html#ref=rss</link>
    <description>Kurz vor Abschluss des Friedensabkommens zwischen USA und Taliban macht Präsident Trump jetzt Halt: Auf Twitter sagte er alle Verhandlungen ab - und verriet, dass heimliche Treffen auf amerikanischem Boden geplant waren.</description>
    <pubDate>Sun, 08 Sep 2019 06:53:00 +0200</pubDate>
    <guid>https://www.spiegel.de/politik/ausland/donald-trump-bricht-friedensverhandlungen-mit-taliban-ab-a-1285764.html</guid>
    <content:encoded>
       <img src="https://www.spiegel.de/images/image-1466888-thumbsmall-dlwf.jpg" hspace="5" align="left" >Kurz vor Abschluss des Friedensabkommens zwischen USA und Taliban macht Präsident Trump jetzt Halt: Auf Twitter sagte er alle Verhandlungen ab - und verriet, dass heimliche Treffen auf amerikanischem Boden geplant waren.
    </content:encoded>
    <enclosure type="image/jpeg" url="https://www.spiegel.de/images/image-1466888-thumbsmall-dlwf.jpg"/>
</item>

Fast alles klappt....ich bekomme nur dieses Element "content:encoded" nicht richtig eingebunden....
Es kommt immer diese Fehlermeldung:
Code:
file:/C:/spiegel_test.xml; lineNumber: 20; columnNumber: 30; Präfix "content" für Element "content:encoded" ist nicht gebunden.

Meine POJO Item sieht so aus:
Code:
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class Item {
    @XmlElement
    private String title;
    @XmlElement
    private String link;
    @XmlElement
    private String description;
    @XmlElement
    private String pubDate;
    @XmlElement
    private String guid;
    @XmlElement(namespace = "content")
    private Encoded encoded;
    @XmlElement
    private Enclosure enclosure;

Und die POJO Encoded so:
Code:
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class Encoded {
    @XmlValue
    private String content;
    @XmlAttribute
    private String src;
    @XmlAttribute
    private String hspace;
    @XmlAttribute
    private String align;

}


Es scheint sich so weit ich im Openbook gelesen hatte um einen namespace zu handeln. Also habe ich das Element mit dem namespace content annotiert, klappt nur nicht :(
Wisst ihr wie ich das richtig hinbekomme? Ist der letzte Knoten, danach passt alles.

Die Aufgabe ist von meiner Schule, ich soll einen RSS Reader schreiben.
Dafür habe ich mir den Spiegel RSS ausgesucht und versuche das nun zu implementieren.
 

DevDomi

Mitglied
Ist ja witzig....mit Vivaldi sehe ich das jetzt auch unter Firefox wird mir das nicht angezeigt. Da starte ich mit <rss version="2.0">
 

DevDomi

Mitglied
Dieser namespace macht mich fertig...
Ich habe das Property nun so annotiert:
@XmlElement(namespace = "http://purl.org/rss/1.0/modules/content/") private Encoded encoded;

Aber aus irgendeinem Grund greift er das nicht beim ausführen des Programms
 

mihe7

Top Contributor
Mal kurz getestet:

Java:
import java.net.*;
import javax.xml.bind.*;

public class Test {
    public static void main(String[] args) throws Exception {
        JAXBContext context = JAXBContext.newInstance(Rss.class);
        Unmarshaller um = context.createUnmarshaller();
        Rss root = (Rss) um.unmarshal(new URL("https://www.spiegel.de/schlagzeilen/tops/index.rss"));
        System.out.println(root.channel.title);
        for (Item item : root.channel.items) {
            System.out.println(item.encoded);
        }
    }
}
Java:
import javax.xml.bind.annotation.*;

@XmlRootElement(name="rss")
public class Rss {
    public Channel channel;
}
Java:
import java.util.*;
import javax.xml.bind.annotation.*;

@XmlRootElement(name="channel")
public class Channel {
    public String title;
    @XmlElement(name="item")
    public List<Item> items;
}
Java:
import javax.xml.bind.annotation.*;

@XmlRootElement(name="item")
public class Item {
    @XmlElement
    public String title;
    @XmlElement(namespace="http://purl.org/rss/1.0/modules/content/")
    public String encoded;
}
 

DevDomi

Mitglied
Der Fehler saß mal wieder 50cm vor dem Monitor.....
Wenn ich den namespace in die POJO packe, sollte ich es auch in der XML nachtragen....

Ich danke dir für die Hilfe! Jetzt klappt es
 
Ähnliche Java Themen

Ähnliche Java Themen

Neue Themen


Oben