2013-01-11 9 views
7

oto banalny fragment z mojego pliku XSDDodanie dodatkowych metod do klasy JAXB wytwarzanej z schematu

<?xml version="1.0" encoding="UTF-8"?> 
<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="ns" 
    xmlns:tns="sns" elementFormDefault="qualified"> 

    <element name="document"> 
     <attribute name="title" use="required"/> 
    </element> 
</schema> 

używam maven-jaxb2-plugin generować klas Java z tego. Klasa Document ma metodę getTitle(), która zwraca tekst atrybutu title.

chcę dodać dodatkową metodę Document:

public String getStrippedTitle() { 
    return getTitle().replaceAll("\\s+", ""); 
} 

Chcę moja dodatkowa metoda pojawiać się na unmarshalled obiektu (zamiast mi tylko nazywając ją albo napisanie klasy otoki), ponieważ chcę, aby przejść najwyższego poziomu unmarshalled obiekt wyłączony do szablonu łańcucha i niech iteruje nad pod-elementami wywołującymi moją dodatkową metodę.

Znalazłem instructions, ale polecono mi ustawić właściwość na Unmarshaller, a moja implementacja (Mac OS X, Java 7) nie obsługuje żadnych właściwości.

Jak powinienem to zrobić?

Odpowiedz

7

Podążając za linkiem podanym przez Briana Henry'ego, stwierdziłem, że mogę wykonać wiążące dostosowanie w pliku schematu, aby zrobić to, co chciałem. Efekt jest dokładnie taki sam, jak rozwiązanie Briana, ale nie wymaga odniesienia do odniesienia do com.sun.xml.internal.

pierwsze, plik zostanie zmodyfikowany nieco schematu:

<schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="ns" 
    xmlns:tns="sns" elementFormDefault="qualified" 
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
jaxb:version="2.0"> 

    <element name="document"> 
     <annotation> 
      <appinfo> 
       <jaxb:class implClass="DocumentEx" /> 
      </appinfo> 
     </annotation> 
     <attribute name="title" use="required"/> 
    </element> 
</schema> 

Gdy schemat zostanie skompilowany do kodu Java, wygenerowany ObjectFactory skieruje do DocumentEx zamiast Document. DocumentEx jest klasa tworzyć, który wygląda tak:

public class DocumentEx extends Document { 
    public String getStrippedTitle() { 
     return getTitle().replaceAll("\\s+", ""); 
    } 
} 

Document (klasa mam rozszerzenie) jest nadal generowany przez kompilator schema-to-Java. Teraz, kiedy wycofać dokument faktycznie uzyskać obiekt DocumentEx:

JAXBContext jaxbContext = JAXBContext.newInstance("com.example.xml"); 
    Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); 
    unmarshaller.setSchema(testSchema); 
    DocumentEx doc = (DocumentEx)unmarshaller.unmarshal(xmlFile); 

Istnieją pewne (trudno parse) Dokumentacja ta w Oracle i kilka pomocnych przykładów w O'Reilly.

2

Możesz spróbować zaktualizować nazwę usługi, którą widzisz w połączonym dokumencie. spróbuj to zamiast:

com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.FACTORY 

lub

"com.sun.xml.internal.bind.ObjectFactory" 

Przypuszczam, że będzie Ci przeszłości PropertyException I postać widzisz. Najbardziej wyczerpująca odpowiedź: here sugeruje, że nie ma gwarancji, że zadziała, ale warto spróbować, odkąd zaszła tak daleko. Kod źródłowy, o ile wyglądałem (nie daleko) wydaje się wspierać tę właściwość.

+0

To działa. Dzięki! Czy masz jakieś sugestie dotyczące lepszej ogólnej metody usuwania pliku XML na klasy Java za pomocą dodatkowych metod? Próbowałem SAX przed JAXB, ale czułem się tak, jakbym właśnie pisał własne (kruche) wdrożenie JAXB. –

+1

@NathanielWaisbrot - Nie trzeba generować modelu JAXB ze schematu XML. Możesz rozpocząć od dowolnego modelu obiektu, który chcesz i użyć adnotacji JAXB do skonfigurowania mapowania XML. –

Powiązane problemy