2012-11-16 37 views
6

मैं कुछ एक्सएमएलसी लिंक मोक्सी के साथ कुछ एक्सएमएल पार्स करने की कोशिश कर रहा हूं, और यह xsi विशेषता के साथ लाइन पर असफल रहा है। अगर मैं इसे हटा देता हूं, तो यह ठीक है। हालांकि, मुझे स्रोत फ़ाइलों को घुमाने और बदलने के लिए 100 जीबीबी एक्सएमएल मिला है, यह विकल्प नहीं है।नामस्थान को गलत तरीके से कैसे सेट किया जाए?

यह सुझाव दिया गया है कि यदि मैं XmlParser.setNamespaceAware(false) सेट कर सकता हूं तो इसे काम करना चाहिए - लेकिन मुझे नहीं पता कि मोक्सी के झटके में सही तरीके से तोड़ने के बिना इसे कैसे कॉन्फ़िगर किया जाए।

<record> 
<header> 
    <!-- citation-id: 14404534; type: journal_article; --> 
    <identifier>info:doi/10.1007/s10973-004-0435-2</identifier> 
    <datestamp>2009-04-28</datestamp> 
    <setSpec>J</setSpec> 
    <setSpec>J:1007</setSpec> 
    <setSpec>J:1007:2777</setSpec> 
</header> 
<metadata> 
    <crossref xmlns="http://www.crossref.org/xschema/1.0" 
     xsi:schemaLocation="http://www.crossref.org/xschema/1.0 http://www.crossref.org/schema/unixref1.0.xsd"> 
     <journal> 
      <journal_metadata language="en"> 
[...] 

अपवाद रहा जब xsi: उपसर्ग मौजूद है:

org.springframework.oxm.UnmarshallingFailureException: JAXB unmarshalling exception; nested exception is javax.xml.bind.UnmarshalException 
- with linked exception: 
[Exception [EclipseLink-25004] (Eclipse Persistence Services - 2.4.0.v20120608-r11652): org.eclipse.persistence.exceptions.XMLMarshalException 
Exception Description: An error occurred unmarshalling the document 
Internal Exception: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[13,107] 
Message: http://www.w3.org/TR/1999/REC-xml-names-19990114#AttributePrefixUnbound?crossref&xsi:schemaLocation&xsi] 
+0

आप जिस मूल समस्या को मार रहे हैं वह क्या है? –

+0

@BlaiseDoughan अपडेट किया गया। वास्तव में उम्मीद है कि आप मदद कर सकते हैं :) –

+0

आपके उपयोग के मामले में क्या आप आवश्यक 'xmlns: xsi' घोषणा जोड़ सकते हैं? वैकल्पिक विकल्प में गोता लगाने से पहले बस जांच करें। –

उत्तर

8

वर्तमान में नामस्थान अनदेखी करने के लिए यह बताने के लिए EclipseLink JAXB (MOXy) में एक विकल्प नहीं है। लेकिन एक दृष्टिकोण है जिसका उपयोग आप एक स्थिर पार्सर का लाभ उठाकर कर सकते हैं।

डेमो

आप एक्सएमएल इनपुट है कि बारे में पता नाम स्थान नहीं पर एक StAX XMLStreamReader बना सकते हैं और फिर उस से MOXY unmarshal है।

package forum13416681; 

import javax.xml.bind.*; 
import javax.xml.stream.*; 
import javax.xml.transform.stream.StreamSource; 

public class Demo { 

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

     XMLInputFactory xif = XMLInputFactory.newFactory(); 
     xif.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, false); 
     StreamSource source = new StreamSource("src/forum13416681/input.xml"); 
     XMLStreamReader xsr = xif.createXMLStreamReader(source); 

     Unmarshaller unmarshaller = jc.createUnmarshaller(); 
     Foo root = (Foo) unmarshaller.unmarshal(xsr); 

     Marshaller marshaller = jc.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 
     marshaller.marshal(root, System.out); 
    } 

} 

जावा मॉडल (फू)

package forum13416681; 

import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Foo { 

    private String bar; 

    public String getBar() { 
     return bar; 
    } 

    public void setBar(String bar) { 
     this.bar = bar; 
    } 

} 

इनपुट (input.xml)

नीचे अपने प्रश्न से XML का एक सरलीकृत संस्करण है। ध्यान दें कि यह एक्सएमएल ठीक से नेमस्पेस योग्य नहीं है क्योंकि यह xsi उपसर्ग के लिए नेमस्पेस घोषणा खो रहा है।

<?xml version="1.0" encoding="UTF-8"?> 
<foo xsi:schemaLocation="http://www.crossref.org/xschema/1.0 http://www.crossref.org/schema/unixref1.0.xsd"> 
    <bar>Hello World</bar> 
</foo> 

आउटपुट

नीचे डेमो कोड को चलने से उत्पादन होता है।

<?xml version="1.0" encoding="UTF-8"?> 
<foo> 
    <bar>Hello World</bar> 
</foo> 
2

बजाय नाम स्थान जागरूकता पूरी तरह अक्षम, आप पहले से xsi उपसर्ग घोषित करने के लिए एक StAX-कार्यान्वयन-विशिष्ट तंत्र का उपयोग करने के लिए, तो नामस्थान सक्षम साथ पार्स कर सकता है। उदाहरण के लिए, Woodstox के साथ कह सकते हैं:

import javax.xml.bind.*; 
import javax.xml.stream.*; 
import javax.xml.transform.stream.StreamSource; 
import com.ctc.wstx.sr.BasicStreamReader; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     JAXBContext jc = JAXBContext.newInstance("com.example"); 

     XMLInputFactory xif = XMLInputFactory.newFactory(); 
     StreamSource source = new StreamSource("input.xml"); 
     XMLStreamReader xsr = xif.createXMLStreamReader(source); 
     ((BasicStreamReader)xsr).getInputElementStack().addNsBinding(
       "xsi", "http://www.w3.org/2001/XMLSchema-instance"); 

और फिर unmarshaller बना सकते हैं और Blaise's answer में के रूप में xsr unmarshal। हालांकि यह स्पष्ट रूप से आपको एक विशिष्ट एसएक्सएक्स कार्यान्वयन से जोड़ता है, इसका मतलब यह है कि यदि आप <crossref> तत्व और उसके बच्चों को http://www.crossref.org/xschema/1.0 नामस्थान में रहने की उम्मीद करते हैं तो आपको अपने मौजूदा जेएक्सबी मॉडल कक्षाओं को संशोधित करने की आवश्यकता नहीं है।