2015-04-14 10 views
6

पर नामस्थान को अनदेखा करता है मैं जैक्सबी 2 और वसंत का उपयोग करता हूं। मैं अपने कुछ ग्राहकों द्वारा भेजे गए कुछ एक्सएमएल को उतारने की कोशिश कर रहा हूं।जैक्सब unmarshalling

<foo xmlns="com.acme"> 
    <bar>[...]</bar> 
<foo> 

है कि इस तरह एक POJO के लिए बाध्य है:

@XmlType(name = "", propOrder = {"bar"}) 
@XmlRootElement(name = "Foo") 
public class Foo { 

    @XmlElement(name = "Bar") 
    private String bar; 

    [...] 
} 

मुझे लगता है कि पिछले खोज की

अब तक, मैं केवल एक ग्राहक जो इस तरह की कुछ xml भेजा संभाल करने के लिए किया था डेवलपर ने इसे काम करने के लिए unmarshaller में नेमस्पेस हार्डकोड किया।

अब, दूसरा ग्राहक एक ही एक्सएमएल भेजता है लेकिन नामस्थान बदलता है!

<foo xmlns="com.xyz"> 
    <bar>[...]</bar> 
<foo> 

जाहिर है, unmarshaller unmarshall क्योंकि यह {com.xyz}foo के बजाय कुछ {com.acme}foo उम्मीद विफल रहता है। अनजाने में, ग्राहक को एक्सएमएल बदलने के लिए कहा एक विकल्प नहीं है।

मैं क्या करने की कोशिश की:

1)application-context.xml में, मैं एक विन्यास जो मुझे नाम स्थान की अनदेखी करने की अनुमति होगी के लिए खोज की, लेकिन एक नहीं पा सके:

<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> 
    <property name="packagesToScan"> 
    <list> 
     <value>com.mycompany.mypkg</value> 
    </list> 
    </property> 
    <property name="marshallerProperties"> 
    <map> 
     <entry key="???"><value type="java.lang.Boolean">false</value></entry> 
    </map> 
    </property> 
</bean> 

ऐसा लगता है कि केवल उपलब्ध विकल्प जैक्सबी 2 मार्शेलर के जावाडोक में सूचीबद्ध हैं:

/** 
* Set the JAXB {@code Marshaller} properties. These properties will be set on the 
* underlying JAXB {@code Marshaller}, and allow for features such as indentation. 
* @param properties the properties 
* @see javax.xml.bind.Marshaller#setProperty(String, Object) 
* @see javax.xml.bind.Marshaller#JAXB_ENCODING 
* @see javax.xml.bind.Marshaller#JAXB_FORMATTED_OUTPUT 
* @see javax.xml.bind.Marshaller#JAXB_NO_NAMESPACE_SCHEMA_LOCATION 
* @see javax.xml.bind.Marshaller#JAXB_SCHEMA_LOCATION 
*/ 
public void setMarshallerProperties(Map<String, ?> properties) { 
    this.marshallerProperties = properties; 
} 

2) मैं भी कोड में unmarshaller कॉन्फ़िगर करने की कोशिश की:

try { 
    jc = JAXBContext.newInstance("com.mycompany.mypkg"); 

    Unmarshaller u = jc.createUnmarshaller(); 
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
    dbf.setNamespaceAware(false);//Tried this option. 

    DocumentBuilder db = dbf.newDocumentBuilder(); 
    Document doc = db.parse(xmlFile.toFile()); 
    u.unmarshal(new DOMSource(doc)); 
    return (Foo)u.unmarshal(new StreamSource(xmlFile.toFile())); 
} catch (ParserConfigurationException | SAXException | IOException | JAXBException e) { 
    LOGGER.error("Erreur Unmarshalling CPL"); 
} 

3) एक SAXParser साथ अलग रूप:

try { 
    jc = JAXBContext.newInstance("com.mycompany.mypkg"); 
    Unmarshaller um = jc.createUnmarshaller(); 
    final SAXParserFactory sax = SAXParserFactory.newInstance(); 
    sax.setNamespaceAware(false); 
    final XMLReader reader = sax.newSAXParser().getXMLReader(); 
    final Source er = new SAXSource(reader, new InputSource(new FileReader(xmlFile.toFile()))); 
    return (Foo)um.unmarshal(er); 
}catch(...) {[...]} 

यह एक काम करता है! लेकिन फिर भी, मैं हर समय इस बदसूरत conf की आवश्यकता के बिना Unmarshaller को स्वत: करने में सक्षम होना पसंद करूंगा।

उत्तर

1

नेमस्पेस जागरूकता दस्तावेज़ पाठक/निर्माता/पार्सर नहीं है जो मार्शलर्स नहीं है। विभिन्न नामस्थानों से एक्सएमएल तत्व अलग-अलग इकाइयों == वस्तुओं का प्रतिनिधित्व करते हैं, इसलिए मार्शलर्स उन्हें अनदेखा नहीं कर सकते हैं।

आपने अपने SAX रीडर में नामस्थानों को सही ढंग से बंद कर दिया है और जैसा कि आपने कहा है कि यह काम करता है। मैं इसके साथ आपकी समस्या को समझ नहीं पा रहा हूं, आपके मार्शलर को अभी भी इंजेक्शन दिया जा सकता है, अंतर इनपुट डेटा प्राप्त करने में अंतर है।

दस्तावेज़ निर्माता के साथ एक ही चाल को भी काम करना चाहिए (मैं बाद में इसका परीक्षण करूंगा), मुझे संदेह है कि आप अभी भी "हार्डकोडेड" नामस्थान के साथ मार्शलर का उपयोग कर रहे थे लेकिन आपका दस्तावेज़ नामस्थान मुक्त था।

मेरी परियोजना में मैं इसी तरह के मुद्दे को हल करने के लिए एक्सएसएलटी का उपयोग करता हूं। नेमस्पेस आवरनेस सेट करना निश्चित रूप से आसान समाधान है। लेकिन, एक्सएसएलटी के साथ मैं केवल कुछ नामस्थानों को चुन सकता हूं और मेरा मेरा इनपुट एक्सएमएल हमेशा समान नहीं है (नेमस्पेस को अनदेखा कर रहा है) और कभी-कभी मुझे कुछ तत्वों का नाम बदलना पड़ता है, इसलिए एक्सएसएलटी मुझे यह अतिरिक्त लचीलापन देता है।

नामस्थान निकालने के लिए आप इस तरह के xslt टेम्पलेट का उपयोग कर सकते हैं:

Transformer transformer = TransformerFactory.newInstance().newTransformer(stylesource); 
Source source = new DOMSource(xml); 
DOMResult result = new DOMResult(); 
transformer.transform(source, result); 
: unmarshalling मैं इनपुट डेटा को बदलने से पहले

<xsl:stylesheet version="1.0" xmlns:e="http://timet.dom.robust.ed" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<xsl:template match="/"> 
    <xsl:copy> 
     <xsl:apply-templates /> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="*"> 
    <xsl:element name="{local-name()}"> 
     <xsl:apply-templates select="@* | node()" /> 
    </xsl:element> 
</xsl:template> 

<xsl:template match="@*"> 
    <xsl:attribute name="{local-name()}"> 
     <xsl:value-of select="."/> 
    </xsl:attribute> 
</xsl:template> 

<xsl:template match="text() | processing-instruction() | comment()"> 
    <xsl:copy /> 
</xsl:template> 
</xsl:stylesheet> 
फिर जावा में

संबंधित मुद्दे