5 Stimmen

JAXB zum Unmarshall von <string>foobar</string>

Grüße! Ich habe einen Server, der XML-Inhalte an meinen Client zurückgibt, die wie folgt aussehen:

<string xmlns="...">foobar</string>

Ich bin neu in JAXB und habe eine Menge Zeug arbeiten, außer dies bekommen. Ich dachte, es wäre ziemlich einfach zu marshal und unmarshal dies zu und von einem String sein. Es hat eine Weile gedauert, aber schließlich habe ich herausgefunden, wie man das als

    public static String ToXML(String s) throws Exception
    {
        JAXBContext context = JAXBContext.newInstance(String.class);
        Marshaller marshaller = context.createMarshaller();
        StringWriter sw = new StringWriter();
        marshaller.marshal(new JAXBElement(new QName("", "String"), String.class, s), sw);

        return sw.toString();
    }

Meine Frage ist also: Wie kann ich das wieder rückgängig machen? Es kann nicht als Root-Element annotiert werden. Ich kann java.lang nicht als Paket verwenden, um eine neue Instanz eines JAXBContext zu erstellen (ich erhalte eine ObjectFactory-Ausnahme).

Haben Sie eine Weisheit zu verkünden? Das kann doch nicht so schwer sein, oder?

11voto

skaffman Punkte 389758

Sie müssen ein Objektmodell schreiben, das mit Ihrer XML-Struktur konform ist, und JAXB anweisen, das Unmarshal auf dieses zu übertragen. Ihr Beispiel mag einfach aussehen, aber dafür ist JAXB nicht gedacht.

Versuchen Sie so etwas:

@XmlRootElement(name="string", namespace="blah")
public class MyString {
   @XmlValue
   String value;
}

JAXBContext context = JAXBContext.newInstance(MyString.class);
MyString myString = (MyString) context.createUnmarshaller().unmarshal(...);

Dadurch wird die XML-Datei entschärft <string xmlns="blah">foobar</string> . Ändern Sie den Namespace entsprechend. Wenn Sie viele Namespaces haben, dann ist JAXB nicht wirklich das richtige Werkzeug für Sie.

8voto

laz Punkte 27769

Das hat mich überrascht, aber das Folgende scheint zu funktionieren:

final String xmlString = "<string>value</string>";
final StringReader xmlReader = new StringReader(xmlString);
final StreamSource xmlSource = new StreamSource(xmlReader);
final JAXBContext jaxbContext = JAXBContext.newInstance(String.class);
final Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
final String stringValue = unmarshaller.unmarshal(xmlSource, String.class).getValue();

Ist es das, wonach Sie gesucht haben?

3voto

Andy Gherna Punkte 2085

Wenn Sie JAXB verwenden, müssen Sie den Code um ein XML-Schema herum aufbauen. Das heißt, wenn Sie eine Datei, z. B. foo.xsd, haben, müssen Sie sie durch den xjc-Compiler laufen lassen (standardmäßig im JDK 6 enthalten, andernfalls können Sie JAXB 2 herunterladen und es verwenden). Dieser liest das Schema ein und generiert die Java Bean und die zugehörigen ObjectFactory-Klassen mit den Elementen im Schema. Die Java-Bean-Klassen werden wie normale POJOs mit Anmerkungen aussehen. Die ObjectFactory-Klassen werden von der JAXB-Implementierung benötigt, um das XML in die entsprechende Java Bean zu konvertieren. Dies erklärt Ihre ObjectFactory-Ausnahme.

Es ist also nicht schwer, aber es ist ein wenig Laufarbeit erforderlich. Wir verwenden es für eine unserer Produktionsanwendungen und es ist großartig. Ich denke, dass ich es jetzt, da es Teil des JDK ist, häufiger verwenden werde.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X