2012-02-15 15 views
7

Mam problemy z pomyślnym zestawieniem przy użyciu właściwości Marshaller.JAXB_FRAGMENT. Oto prosta wersja XML, którą próbuję wydrukować.JAXB Fragmented Marshalling

<Import> 
    <WorkSets> 
     <WorkSet> 
      <Work> 
      <Work> 
      ... 
      .. 
      ... 
     </WorkSet> 
     <WorkSet> 
      <Work> 
      <Work> 
      ... 
     </WorkSet> 
    <WorkSets> 
<Import> 

W <Import> i <WorkSets> elementy są zasadniczo tylko elementów kontenerów, które otaczają dużą liczbę <WorkSet> & <Work> elementów. Obecnie próbuję przeprowadzić operację pod numerem <WorkSet>.

  1. Czy możliwe jest początkowo Marszałka <Import> i <WorkSets> elementy, a następnie od tej pory marszałka na elemencie <WorkSet> i posiada wyjście być ujęty w <Import><WorkSets> tagów?
  2. Kiedy przechwytywam na poziomie WorkSet, dołącza on atrybut xmlns='http://namespace.com' do tagu WorkSet, czy istnieje sposób na wykonanie polecenia bez dołączenia atrybutu przestrzeni nazw do zestawu roboczego?
+0

Nie jestem pewien, czy Cię rozumiem. Czym są "i elementy"? Widzę tylko WorkSet, WorkSets i Import. Co masz na myśli, gdy mówisz: "... najpierw uporządkuj i elementy, a potem od tej chwili na Marshall w żywiole ..."? – AlexR

+0

@AlexR Kiedy po raz pierwszy opublikowałem pytanie, nie wyświetlałem tagów w pytaniach, zredagowałem go tak, aby były teraz wyświetlane, daj mi znać, jeśli nie są. – TyC

+0

Dlaczego powielono pytanie jako [JAXB Fragment Marshal w/o namespace] (http://stackoverflow.com/questions/9297872), jeśli zaakceptowałeś odpowiedź w tym poście? Przynajmniej wspomnij, że pytanie zostało rozwidlone ... –

Odpowiedz

17

Zasadniczo brzmi to raczej niż konstruowanie drzewa obiektów pełnych z obiektami kontenera, aby móc przesyłać strumieniowo kolekcję instancji WorkSet do marszałka przy użyciu JAXB.

Podejście, które chciałbym podjąć, to użycie obiektu XMLStreamWriter i przeprowadzenie inspekcji obiektów WorkSet poprzez zawijanie ich w obiekcie JAXBElement. Nie testowałem przykładowy kod pod ręką, więc tutaj jest szorstki fragment kodu, który należy umieścić na torze napisać:

FileOutputStream fos = new FileOutputStream("foo.xml"); 
XMLStreamWriter writer = XMLOutputFactory.newFactory().createXMLStreamWriter(fos); 

writer.writeStartDocument(); 
writer.writeStartElement("Import"); 
writer.writeStartElement("WorkSets"); 

JAXBContext context = JAXBContext.newInstance(WorkSet.class); 
Marshaller m = context.createMarshaller(); 
m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); 
for (WorkSet instance : instances) 
{ 
    JAXBElement<WorkSet> element = new JAXBElement<WorkSet>(QName.valueOf("WorkSet"), WorkSet.class, instance); 
    m.marshal(element, writer); 
} 

writer.writeEndDocument(); // this will close any open tags 
writer.close(); 

Uwaga: Powyższe jest całkowicie niesprawdzone i mogą być aprowizacji coś w część owijająca do napisania każdej instancji WorkSet. Musisz zawinąć instancje WorkSet, ponieważ nie będą one opatrzone adnotacją @XmlRootElement, a JAXB w przeciwnym razie odmówi przeprowadzenia marszu obiektów.

+0

Dzięki @ JörnHorstmann, zapomniałem o części fragmentu i właśnie wróciłem, aby dodać ją w sobie. – Ophidian

+1

Dzięki! Po prostu spróbowałem i wygląda na to, że działa dobrze.Dodałem drugie pytanie, kiedy instancje WorkSet są układane, atrybut xmlns jest dołączany do każdego elementu WorkSet z jakiegoś powodu, czy istnieje sposób, aby nie przypisywać tego atrybutu podczas ich zbierania? – TyC

+0

To, jestem całkowicie niepewny. Zaczynam uważnie czytać javadocsów JAXB. Przepraszam! – Ophidian

0

Innym podejściem może być po prostu owinięcie przychodzącego xml elementami wymaganymi do utworzenia elementu głównego. Następnie pobierz obiekt Java dla elementu głównego i wywołaj getter dla fragmentu, którego szukasz.

Na przykład, jeśli miał xml jak poniżej:

<XmlRootElement> 
    <FragmentElement> 
     <foo>This is the foo value</foo> 
     <bar>This is the bar value</bar> 
    </FragmentElement> 
</XmlRootElement> 

I wręczono to:

<FragmentElement> 
    <foo>This is the foo value</foo> 
    <bar>This is the bar value</bar> 
</FragmentElement> 

Można owinąć łańcuch z tagami XmlRootElement a następnie zanalizować wynikowy ciąg znaków w obiekt główny i pobrać z niego obiekt fragmentu. Coś takiego:

public FragementElement getFragmentElement(String xml) { 
    xml = "<XmlRootElement>" + xml + "</XmlRootElement>"; 
    ByteArrayInputStream is = new ByteArrayInputStream(xml.getBytes()); 
    JAXBElement obj = (JAXBElement) unmarshaller.unmarshal(is); 
    XmlRootElement xmlRootElement = (XmlRootElement) obj.getValue(); 
    FragementElement fragmentElement = xmlRootElement.getText(); 
    return fragmentElement; 
}