java - JAXB 是否支持默认模式值?

标签 java xml schema jaxb

我有一个定义元素和属性默认值的架构。我正在尝试使用基于该架构的 JAXB 解析文档,但 JAXB 未设置默认值。关于如何让 JAXB 遵循模式中的默认值有什么想法吗?

例子.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>

测试解析器.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();
        }
    }
}

根元素.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;
    }

}

最佳答案

元素默认值

要获取元素属性的默认值,您需要按如下方式对其进行注释:

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

属性默认值

如果您使用 EclipseLink JAXB (MOXy)您将使用您提供的代码获得默认属性值。 JAXB 的 Metro 实现中可能存在阻止此功能工作的错误。请注意,我负责 MOXy 的实现。


替代方法

以下代码应该适用于任何 JAXB 实现,而无需对您的模型进行任何代码更改。您可以执行以下操作并利用 SAXSource:

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();
        }
    }
}

关于java - JAXB 是否支持默认模式值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5423414/

相关文章:

php - 简单计划 - 模式数据库

hadoop - 动态模式的解决方案 - HIVE/AVRO

java - Spring中使用注解与XML配置的情况?

java - 如何在 Java 中从 Stack 接收前一行文本

java - 我们如何在java中使用JAXB创建通用对象

c# - 字符串转义为 XML

json - 在PIG的JsonLoader中定义架构

java - 通过java在mysql中保存俄语

java - 如何检查一个对象是否是某种类型的数组

android - Gradle脚本XML转换