2011-03-24 12 views
5

मेरे पास एक स्कीमा है जो तत्वों और विशेषताओं के लिए डिफ़ॉल्ट मानों को परिभाषित करती है। मैं उस स्कीमा के आधार पर जेएक्सबी का उपयोग कर दस्तावेज़ को पार्स करने की कोशिश कर रहा हूं लेकिन जेएक्सबी डिफ़ॉल्ट मान निर्धारित नहीं कर रहा है। जेएक्सबी को स्कीमा से डिफ़ॉल्ट मानों को सम्मानित करने के तरीके पर कोई विचार है?क्या JAXB डिफ़ॉल्ट स्कीमा मानों का समर्थन करता है?

example.xsd:

<?xml version="1.0" encoding="UTF-8"?><xs:schemaxmlns:xs="http://www.w3.org/2001/XMLSchema" 
targetNamespace="http://www.example.org/example" 
xmlns:tns="http://www.example.org/example"> 

<xs:element name="root" type="tns:rootType"/> 

<xs:complexType name="rootType"> 
    <xs:sequence> 
     <xs:element name="child" type="tns:childType"/> 
    </xs:sequence> 
</xs:complexType> 

<xs:complexType name="childType"> 
    <xs:sequence> 
     <xs:element name="childVal" type="xs:string" default="defaultElVal"/> 
    </xs:sequence> 
    <xs:attribute name="attr" type="xs:string" default="defaultAttrVal"/> 
</xs:complexType> 

example1.xml

<?xml version="1.0" encoding="UTF-8"?> 
<tns:root xmlns:tns="http://www.example.org/example" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/example example.xsd "> 
    <child> 
    <childVal/> 
    </child> 
</tns:root> 

TestParser.java

package test; 
import java.io.File; 
import javax.xml.XMLConstants; 
import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Unmarshaller; 
import javax.xml.validation.Schema; 
import javax.xml.validation.SchemaFactory; 
public class TestParser {  
    public static void main(String[] pArgs) { 
     try { 
      JAXBContext context = JAXBContext.newInstance(RootElement.class); 
      Unmarshaller unmarshaller = context.createUnmarshaller(); 

      SchemaFactory schemaFac = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
      Schema sysConfigSchema = schemaFac.newSchema(
        new File("example.xsd")); 
      unmarshaller.setSchema(sysConfigSchema); 
      RootElement root = (RootElement)unmarshaller.unmarshal(
        new File("example1.xml")); 
      System.out.println("Child Val: " + root.getChild().getChildVal()); 
      System.out.println("Child Attr: " + root.getChild().getAttr()); 
     } catch (Exception e) { 
      System.out.println(e.getMessage()); 
      e.printStackTrace(); 
     } 
    } 
} 

RootElement.java

package test; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement(name="root", namespace="http://www.example.org/example") 
public class RootElement { 

    private ChildEl child; 

    public RootElement() {} 

    public ChildEl getChild() { 
     return child; 
    } 

    public void setChild(ChildEl pChild) { 
     this.child = pChild; 
    } 
} 

ChildEl.java

package test; 

import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement(name="child") 
public class ChildEl { 

    private String attr; 
    private String childVal; 

    public ChildEl() {}; 

    @XmlAttribute 
    public String getAttr() { 
     return attr; 
    } 
    public void setAttr(String pAttr) { 
     this.attr = pAttr; 
    } 

    public String getChildVal() { 
     return childVal; 
    } 
    public void setChildVal(String pVal) { 
     this.childVal = pVal; 
    } 

} 

उत्तर

9

तत्व डिफ़ॉल्ट मान

आप उस पर टिप्पणी करने के लिए इस प्रकार की जरूरत तत्व संपत्ति पर डिफ़ॉल्ट मान प्राप्त करने के लिए:

@XmlElement(defaultValue="defaultElVal") 
public String getChildVal() { 
    return childVal; 
} 

विशेषता डिफ़ॉल्ट मान

यदि आप EclipseLink JAXB (MOXy) का उपयोग करते हैं तो आपको आपके द्वारा प्रदान किए गए कोड का उपयोग करके डिफ़ॉल्ट विशेषता मान प्राप्त होगा। जेएक्सबी के मेट्रो कार्यान्वयन में एक बग हो सकती है जो इसे काम करने से रोक रही है। नोट मैं MOXy कार्यान्वयन का नेतृत्व करता हूं।


वैकल्पिक दृष्टिकोण

निम्नलिखित कोड अपने मॉडल के लिए किसी भी कोड में परिवर्तन की आवश्यकता के बिना किसी भी JAXB कार्यान्वयन के साथ काम करना चाहिए।

import java.io.File; 
import java.io.FileInputStream; 

import javax.xml.XMLConstants; 
import javax.xml.bind.JAXBContext; 
import javax.xml.bind.Unmarshaller; 
import javax.xml.parsers.SAXParserFactory; 
import javax.xml.transform.sax.SAXSource; 
import javax.xml.validation.Schema; 
import javax.xml.validation.SchemaFactory; 

import org.xml.sax.InputSource; 
import org.xml.sax.XMLReader; 
public class TestParser {  
    public static void main(String[] pArgs) { 
     try { 
      JAXBContext context = JAXBContext.newInstance(RootElement.class); 
      Unmarshaller unmarshaller = context.createUnmarshaller(); 

      SchemaFactory schemaFac = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
      Schema sysConfigSchema = schemaFac.newSchema(
        new File("example.xsd")); 

      SAXParserFactory spf = SAXParserFactory.newInstance(); 
      spf.setNamespaceAware(true); 
      spf.setSchema(sysConfigSchema); 
      XMLReader xmlReader = spf.newSAXParser().getXMLReader(); 
      SAXSource source = new SAXSource(xmlReader, new InputSource(new FileInputStream("example1.xml"))); 
      RootElement root = (RootElement)unmarshaller.unmarshal(
        source); 
      System.out.println("Child Val: " + root.getChild().getChildVal()); 
      System.out.println("Child Attr: " + root.getChild().getAttr()); 
     } catch (Exception e) { 
      System.out.println(e.getMessage()); 
      e.printStackTrace(); 
     } 
    } 
} 
4

मुझे लगता है कि आप विशेष रूप से गुण बनाम सरल तत्वों के साथ सद्भाव के लिए के रूप में समझदार ऐसा करने के लिए, कोशिश कर रहे हैं क्या आप निम्न और लाभ उठाने SAXSource कर सकता है। यह मुझे अजीब लगता है, लेकिन ऐसा लगता है कि jaxb2 कार्यान्वयनकर्ता एक्सटेंशन का एक अतिरिक्त सेट जोड़ना चुनते हैं जिसे आपको वांछित व्यवहार प्राप्त करने के लिए जोड़ना होता है। देखें:।

(मैं नहीं बल्कि और अधिक प्राकृतिक डिफ़ॉल्ट व्यवहार और गुण और कम से कम सरल प्रकार के तत्वों के बीच सामंजस्य देखा होगा - एक प्लगइन पंजीकृत हुए बिना फिर एक प्लग प्रदान विशेष मामलों के लिए। मेरे एकमात्र लोग क्यों नहीं किए गए थे या पीछे की संगतता - अनुमान।)

जैक्सबी 2-कॉमन्स डिफ़ॉल्ट मान प्लगइन आपके द्वारा जोड़े गए अतिरिक्त आदेश (और जार) को संदर्भित करता है xjc जो बदले में डिफ़ॉल्ट व्यवहार जोड़ता है मैदान में।(। कहाँ, बेशक, सशर्त अशक्त जांच डिफ़ॉल्ट मान या नहीं प्रस्तुत करता है): मेरे मामले में

public String getScalarOptionalMaxAndDefaultString() { 
    if (scalarOptionalMaxAndDefaultString == null) { 
     return "def val 1"; 
    } else { 
     return scalarOptionalMaxAndDefaultString; 
    } 
} 

ब्लेज Doughan का उपयोग करते हुए चारों ओर एक व्यावहारिक काम की तरह लगता है। अपने एक्सएमएल दस्तावेज़ की प्रकृति के आधार पर, यह सही हो सकता है।

फिर भी, ऐसा लगता है कि यह डिफ़ॉल्ट वैल्यू प्लगइन निर्माण प्रक्रिया में समाधान को स्थानांतरित कर सकता है और आपके कोड में कोई बदलाव नहीं देख सकता (मान लीजिए कि आप सैक्स पार्सर ब्लेज़ के विपरीत डोम का उपयोग कर रहे हैं)।

ऐसा लगता है कि डिफ़ॉल्ट-मूल्य प्लगइन समस्या को हल करता है और संभावित रूप से अतिरिक्त एक्स्टेंसिबिलिटी (ऐसी उन्नत अनुकूलन की आवश्यकता नहीं है) प्रदान करता है, आपको संभावित प्रोग्रामिंग डिफ़ॉल्ट मान नियंत्रण xjc चलाने की आवश्यकता होती है।

यहाँ एक Maven config टुकड़ा मामले में यह मदद करता है:

<plugin> 
    <groupId>org.jvnet.jaxb2.maven2</groupId> 
    <artifactId>maven-jaxb2-plugin</artifactId> 
    <version>0.8.0</version> 
    <executions> 
     <execution> 
     <phase>generate-sources</phase> 
     <goals> 
      <goal>generate</goal> 
     </goals> 
     <configuration> 
      <args> 
       <arg>-Xdefault-value</arg> 
      </args> 
      <plugins> 
       <plugin> 
        <groupId>org.jvnet.jaxb2_commons</groupId> 
        <artifactId>jaxb2-default-value</artifactId> 
        <version>1.1</version> 
       </plugin> 
      </plugins> 
     </configuration> 
     </execution> 
    </executions> 
    <configuration><schemaDirectory>src/test/resources</schemaDirectory></configuration> 
    </plugin> 
1

डिफ़ॉल्ट मान सेट एक beforeMarshal (Marshaller marshaller) समारोह हो सकता है के लिए एक और तरीका है:

private void beforeMarshal(Marshaller marshaller) { 
    childVal = (null == getChildVal) ? CHILD_VAL_DEFAULT_VALUE : childVal; } 
संबंधित मुद्दे