2011-08-03 10 views
6

दौरान XML प्रोसेसिंग निर्देश जोड़ने के लिए मैं एक प्रोसेसिंग निर्देश जब भी एक संग्रह/सरणी संपत्ति की तरहकैसे JAXB मार्शल

<alice> 
    <? array bob ?> 
    <bob>edgar</bob> 
    <bob>david</bob> 
</alice> 

कुछ पाने के लिए धारावाहिक है जोड़ना चाहते हैं इस JAXB के साथ संभव है? या कम से कम कुछ विशिष्ट JAXB कार्यान्वयन के साथ? XmlAdapter बारे में ध्यान देने

BobAdapter

हालात:

उत्तर

6

आप का लाभ उठाने सकता है एक XMLStreamWriter और एक XmlAdapter यह करने के लिए

  • यह स्टेटफुल है और उसका संदर्भ XMLStreamWriter। हम बाद में Marshaller पर एक राज्यव्यापी XmlAdapter सेट करने के लिए जेएक्सबी की क्षमता का लाभ उठाएंगे।
  • यह List<String> से List<String> में परिवर्तित हो जाता है, हम केवल एक ईवेंट प्राप्त करने के लिए XmlAdapter का उपयोग कर रहे हैं।
  • marshal विधि है, जहां हम XMLStreamWriter पर writeProcessingInstruction फोन:

 

package forum6931520; 

import java.util.List; 

import javax.xml.bind.annotation.adapters.XmlAdapter; 
import javax.xml.stream.XMLStreamWriter; 

public class BobAdapter extends XmlAdapter<List<String>, List<String>> { 

    private boolean first = true; 
    private XMLStreamWriter xmlStreamWriter; 

    public BobAdapter() { 
    } 

    public BobAdapter(XMLStreamWriter xmlStreamWriter) { 
     this(); 
     this.xmlStreamWriter = xmlStreamWriter; 
    } 

    @Override 
    public List<String> marshal(List<String> stringList) throws Exception { 
     if(first) { 
      xmlStreamWriter.writeProcessingInstruction("array", "bob"); 
      first = false; 
     } 
     return stringList; 
    } 

    @Override 
    public List<String> unmarshal(List<String> stringList) throws Exception { 
     return stringList; 
    } 

} 

ऐलिस

@XmlJavaTypeAdapter एनोटेशन क्षेत्र/संपत्ति के साथ XmlAdapter लिंक करने के लिए प्रयोग किया जाता है :

package forum6931520; 

import java.util.List; 

import javax.xml.bind.annotation.XmlRootElement; 
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; 

@XmlRootElement 
public class Alice { 

    private List<String> bob; 

    @XmlJavaTypeAdapter(BobAdapter.class) 
    public List<String> getBob() { 
     return bob; 
    } 

    public void setBob(List<String> bob) { 
     this.bob = bob; 
    } 

} 

डेमो

package forum6931520; 

import java.io.File; 

import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Marshaller; 
import javax.xml.bind.Unmarshaller; 
import javax.xml.stream.XMLOutputFactory; 
import javax.xml.stream.XMLStreamWriter; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance(Alice.class); 

     File xml = new File("src/forum6931520/input.xml"); 
     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     Alice alice = (Alice) unmarshaller.unmarshal(xml); 

     Marshaller marshaller = jc.createMarshaller(); 
     XMLOutputFactory xof = XMLOutputFactory.newFactory(); 
     XMLStreamWriter xmlStreamWriter = xof.createXMLStreamWriter(System.out); 
     marshaller.setAdapter(new BobAdapter(xmlStreamWriter)); 
     marshaller.marshal(alice, xmlStreamWriter); 
    } 

} 

इनपुट।एक्सएमएल

<?xml version="1.0" encoding="UTF-8"?> 
<alice> 
    <?array bob?> 
    <bob>edgar</bob> 
    <bob>david</bob> 
</alice> 

आउटपुट

<?xml version='1.0' encoding='UTF-8'?><alice><?array bob?><bob>edgar</bob><bob>david</bob></alice> 

नोट

यह उदाहरण JAXB आरआई के रूप में EclipseLink JAXB (MOXy) के साथ चलाने के किए जाने की आवश्यकता निम्न अपवाद (मैं MOXY नेतृत्व कर रहा हूँ फेंक होगा):

Exception in thread "main" com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 2 counts of IllegalAnnotationExceptions 
java.util.List is an interface, and JAXB can't handle interfaces. 
    this problem is related to the following location: 
     at java.util.List 
     at public java.util.List forum6931520.Alice.getBob() 
     at forum6931520.Alice 
java.util.List does not have a no-arg default constructor. 
    this problem is related to the following location: 
     at java.util.List 
     at public java.util.List forum6931520.Alice.getBob() 
     at forum6931520.Alice 

अधिक जानकारी के लिए


अद्यतन

मैं एक वृद्धि अनुरोध दर्ज किया है (https://bugs.eclipse.org/354286) प्रसंस्करण निर्देशों के लिए मूल समर्थन जोड़ने के लिए। यह अंततः आपको अपनी संपत्ति पर निम्न निर्दिष्ट करने की अनुमति देगा:

@XmlProcessingInstruction(target="array", value="bob") 
public List<String> getBob() { 
    return bob; 
} 
+0

धन्यवाद, मैं इसे MOXy के साथ आज़माउंगा। @ प्रोसेसिंग इंस्ट्रक्शन एनोटेशन निश्चित रूप से अच्छा होगा। हालांकि, जैसा कि मैं किसी भी सूची के लिए पीआई जोड़ना चाहता हूं, मॉडल में सभी सूची गुणों के लिए एनोटेशन जोड़ने के लिए कुछ हद तक असुविधाजनक होगा। क्या XmlAdapter को विश्व स्तर पर पंजीकृत करने का कोई तरीका है? – chris

+0

@ क्रिस - आप एक्सएमएलएडाप्टर को पैकेज स्तर पर '@ XmlJavaTypeAdapters' के साथ पंजीकृत कर सकते हैं (http://blog.bdoughan.com/2011/05/jaxb-and-joda-time-dates-and-times.html देखें)। हालांकि, चूंकि आपके पास विभिन्न प्रकार की सामग्री के साथ सूची होगी, यह आपके लिए काम नहीं करेगा। साथ ही मैं अनुमान लगा रहा हूं कि पीआई की सामग्री प्रति संपत्ति अलग होगी, साथ ही इसका मतलब है कि प्रति संपत्ति समाधान बेहतर काम करेगा। –

+0

ठीक है, धन्यवाद। दुर्भाग्यवश, मार्शल (...) विधि में संपत्ति/तत्व के बारे में कोई जानकारी नहीं है। इसका मतलब यह होगा कि मुझे प्रत्येक सूची संपत्ति के लिए एडाप्टर क्लास को कार्यान्वित करना था। हम्म ... @ प्रसंस्करण निर्देश एनोटेशन अच्छा होगा। – chris