2017-08-08 1 views
1

Mit Hilfe von JAXB möchte ich einige Marshaling und Unmarshalling durchführen, indem ich einige vorhandene XML/Klassen ohne JAXB Typ/Element-Annotationen wiederverwende.JAXB Standard-Namenskonvertierung ändern

Ist es möglich, die standardmäßige JAXB-Namenszuordnungskonfiguration zu ändern, um alle Tags/Felder wie "firstName-> FirstName" zuzuordnen, ohne dass Anmerkungen eingefügt werden?

Ich meine diese Klassenfelder (Anmerkung: sie mit kleinen Buchstaben beginnen)

class Person { 
    String firstName; 
    String lastName; 
} 

zu diesem XML abzubilden (Anmerkung: sie mit dem Großbuchstaben beginnen):

<Person> 
    <FirstName>John</FirstName> 
    <LastName>Doe</LastName> 
</Person> 
+0

Ich glaube nicht, dass die JAXB-Implementierung im JDK dies tun kann. Wenn Sie eine alternative Implementierung wie EclipseLink MOXy verwenden, ist dies möglicherweise möglich. Siehe: [Anpassen von XML-Namenskonvertierungen] (http://www.eclipse.org/eclipselink/documentation/2.6/moxy/advanced_concepts002.htm#CHDCCCAF) – Jesper

+0

Danke, @Jesper. Ich habe gesehen, dass diese Annotation 'XMLNameTransformer' den Job erledigt, aber keine neuen Bibliotheksabhängigkeiten einführen will. –

Antwort

2

Eine Alternative zu Jespers Vorschlag, MOXy zu verwenden, ist das Filtern der Eingabe- und Ausgabe-XML unter Verwendung von StreamReaderDelegate und DelegatingXMLStreamWriter.

Für unmarshalling Sie tun können:

String xml = "<Person><FirstName>John</FirstName><LastName>Doe</LastName></Person>"; 

XMLStreamReader xsr = XMLInputFactory.newInstance().createXMLStreamReader(new StringReader(xml)); 
xsr = new StreamReaderDelegate(xsr) { 
    @Override 
    public String getLocalName() { 
     String s = super.getLocalName(); 
     return Character.toLowerCase(s.charAt(0)) + s.substring(1); 
    } 
}; 

JAXBContext jc = JAXBContext.newInstance(Person.class); 
Unmarshaller u = jc.createUnmarshaller(); 
Person person = u.unmarshal(xsr, Person.class).getValue(); 

Und simillary für marshling:

StringWriter sw = new StringWriter(); 
XMLStreamWriter xsw = XMLOutputFactory.newInstance().createXMLStreamWriter(sw); 
xsw = new DelegatingXMLStreamWriter(xsw) { 
    @Override 
    public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException { 
     String s = localName; 
     super.writeStartElement(prefix, Character.toUpperCase(s.charAt(0)) + s.substring(1), namespaceURI); 
    } 
}; 

Marshaller m = jc.createMarshaller(); 
JAXBElement<Person> jaxbElement = new JAXBElement<Person>(new QName(Person.class.getSimpleName()), Person.class, person); 
m.marshal(jaxbElement, xsw); 

DelegatingXMLStreamWriter ist aus irgendeinem Grund Paket privat, aber es ist eine einfache Klasse, und man kann nur die Quelle, aus here kopieren .

Diese Lösung basiert auf this blog post.

+0

Danke, @Oleg. Klappt wunderbar. Ich dachte, eine Art XML-Preprocessing/Transformation könnte den Job erledigen, aber das ist eine viel bessere Lösung. –