草庐IT

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

coder 2024-03-10 原文

我有一个定义元素和属性默认值的架构。我正在尝试使用基于该架构的 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/

有关java - JAXB 是否支持默认模式值?的更多相关文章

  1. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  2. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  3. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  4. ruby - 默认情况下使选项为 false - 2

    这是在Ruby中设置默认值的常用方法:classQuietByDefaultdefinitialize(opts={})@verbose=opts[:verbose]endend这是一个容易落入的陷阱:classVerboseNoMatterWhatdefinitialize(opts={})@verbose=opts[:verbose]||trueendend正确的做法是:classVerboseByDefaultdefinitialize(opts={})@verbose=opts.include?(:verbose)?opts[:verbose]:trueendend编写Verb

  5. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  6. ruby - 检查数组是否在增加 - 2

    这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife

  7. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  8. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  9. ruby-on-rails - 在默认方法参数中使用 .reverse_merge 或 .merge - 2

    两者都可以defsetup(options={})options.reverse_merge:size=>25,:velocity=>10end和defsetup(options={}){:size=>25,:velocity=>10}.merge(options)end在方法的参数中分配默认值。问题是:哪个更好?您更愿意使用哪一个?在性能、代码可读性或其他方面有什么不同吗?编辑:我无意中添加了bang(!)...并不是要询问nobang方法与bang方法之间的区别 最佳答案 我倾向于使用reverse_merge方法:option

  10. ruby - 检查字符串是否包含散列中的任何键并返回它包含的键的值 - 2

    我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案

随机推荐