尽管用于XML绑定的Java体系结构 ( JAXB )在名义情况下(尤其是自Java SE 6以来) 相当容易使用,但它也存在许多细微差别。 一些常见的细微差别是由于无法将 XML模式定义 (XSD)类型与Java 类型精确匹配 ( 绑定 )。 这篇文章看一个具体的例子,它还演示了当JAXB编译器生成Java类时,实施相同XML结构的不同XSD构造如何导致不同的Java类型。

下一个代码清单(用于Food.xsd )定义了食物类型的架构。 XSD要求有效的XML将具有一个称为“食物”的根元素,该元素具有三个嵌套元素“蔬菜”,“水果”和“甜点”。 尽管用于指定“ Vegetable”和“ Dessert”元素的方法与用于指定“ Fruit”元素的方法不同,但是两种方法都导致相似的“有效XML”。 “ Vegetable”和“ Dessert”元素直接声明为稍后在XSD中定义的指定simpleType的元素。 “水果”元素是通过引用( ref= )定义到另一个包含simpleType定义元素的。

Food.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"xmlns:dustin="http://marxsoftware.blogspot.com/foodxml"targetNamespace="http://marxsoftware.blogspot.com/foodxml"elementFormDefault="qualified"attributeFormDefault="unqualified"><xs:element name="Food"><xs:complexType><xs:sequence><xs:element name="Vegetable" type="dustin:Vegetable" /><xs:element ref="dustin:Fruit" /><xs:element name="Dessert" type="dustin:Dessert" /></xs:sequence></xs:complexType></xs:element><!--Direct simple type that restricts xs:string will become enum inJAXB-generated Java class.--><xs:simpleType name="Vegetable"><xs:restriction base="xs:string"><xs:enumeration value="Carrot"/><xs:enumeration value="Squash"/><xs:enumeration value="Spinach"/><xs:enumeration value="Celery"/></xs:restriction></xs:simpleType><!--Simple type that restricts xs:string but is wrapped in xs:element(making it an Element rather than a SimpleType) will become JavaString in JAXB-generated Java class for Elements that reference it.--><xs:element name="Fruit"><xs:simpleType><xs:restriction base="xs:string"><xs:enumeration value="Watermelon"/><xs:enumeration value="Apple"/><xs:enumeration value="Orange"/><xs:enumeration value="Grape"/></xs:restriction></xs:simpleType></xs:element><!--Direct simple type that restricts xs:string will become enum inJAXB-generated Java class.        --><xs:simpleType name="Dessert"><xs:restriction base="xs:string"><xs:enumeration value="Pie"/><xs:enumeration value="Cake"/><xs:enumeration value="Ice Cream"/></xs:restriction></xs:simpleType></xs:schema>

尽管在模式中对Vegetable元素和Dessert元素的定义与对Fruit定义不同,但是生成的有效XML是相同的。 接下来在food1.xml的代码清单中显示一个有效的XML文件。

food1.xml

<?xml version="1.0" encoding="utf-8"?>
<Food xmlns="http://marxsoftware.blogspot.com/foodxml"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Vegetable>Spinach</Vegetable><Fruit>Watermelon</Fruit><Dessert>Pie</Dessert>
</Food>

此时,我将使用一个简单的Groovy脚本针对上述XSD验证上述XML。 接下来显示此Groovy XML验证脚本的代码( validateXmlAgainstXsd.groovy )。

validateXmlAgainstXsd.groovy

#!/usr/bin/env groovy// validateXmlAgainstXsd.groovy
//
// Accepts paths/names of two files. The first is the XML file to be validated
// and the second is the XSD against which to validate that XML.if (args.length < 2)
{println "USAGE: groovy validateXmlAgainstXsd.groovy <xmlFile> <xsdFile>"System.exit(-1)
}String xml = args[0]
String xsd = args[1]import javax.xml.validation.Schema
import javax.xml.validation.SchemaFactory
import javax.xml.validation.Validatortry
{SchemaFactory schemaFactory =SchemaFactory.newInstance(javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI)Schema schema = schemaFactory.newSchema(new File(xsd))Validator validator = schema.newValidator()validator.validate(new javax.xml.transform.stream.StreamSource(xml))
}
catch (Exception exception)
{println "\nERROR: Unable to validate ${xml} against ${xsd} due to '${exception}'\n"System.exit(-1)
}
println "\nXML file ${xml} validated successfully against ${xsd}.\n"

下一个屏幕快照展示了针对food1.xmlFood.xsd运行上述Groovy XML验证脚本。

到目前为止,本文的目的是展示XSD中的不同方法如何导致相同的XML有效。 尽管这些不同的XSD方法规定了相同的有效XML,但是当使用JAXB生成基于XSD的类时,它们会导致不同的Java类行为。 下一个屏幕快照展示了针对Food.xsd运行JDK提供的JAXB xjc编译器以生成Java类。

上面显示的JAXB生成的输出表明Java类是为“ Vegetable”和“ Dessert”元素创建的,而不是为“ Fruit”元素创建的。 这是因为在XSD中,“蔬菜”和“甜点”的定义与“水果”不同。 下一个代码清单是由xjc编译器生成的Food.java类的。 从中我们可以看到生成的Food.java类引用了针对VegetableDessert特定生成的Java类型,但是仅引用了Fruit的通用Java字符串。

Food.java(由JAXB jxc编译器生成)

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2015.02.11 at 10:17:32 PM MST
//package com.blogspot.marxsoftware.foodxml;import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlSchemaType;
import javax.xml.bind.annotation.XmlType;/*** <p>Java class for anonymous complex type.* * <p>The following schema fragment specifies the expected content contained within this class.* * <pre>* <complexType>*   <complexContent>*     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">*       <sequence>*         <element name="Vegetable" type="{http://marxsoftware.blogspot.com/foodxml}Vegetable"/>*         <element ref="{http://marxsoftware.blogspot.com/foodxml}Fruit"/>*         <element name="Dessert" type="{http://marxsoftware.blogspot.com/foodxml}Dessert"/>*       </sequence>*     </restriction>*   </complexContent>* </complexType>* </pre>* * */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {"vegetable","fruit","dessert"
})
@XmlRootElement(name = "Food")
public class Food {@XmlElement(name = "Vegetable", required = true)@XmlSchemaType(name = "string")protected Vegetable vegetable;@XmlElement(name = "Fruit", required = true)protected String fruit;@XmlElement(name = "Dessert", required = true)@XmlSchemaType(name = "string")protected Dessert dessert;/*** Gets the value of the vegetable property.* * @return*     possible object is*     {@link Vegetable }*     */public Vegetable getVegetable() {return vegetable;}/*** Sets the value of the vegetable property.* * @param value*     allowed object is*     {@link Vegetable }*     */public void setVegetable(Vegetable value) {this.vegetable = value;}/*** Gets the value of the fruit property.* * @return*     possible object is*     {@link String }*     */public String getFruit() {return fruit;}/*** Sets the value of the fruit property.* * @param value*     allowed object is*     {@link String }*     */public void setFruit(String value) {this.fruit = value;}/*** Gets the value of the dessert property.* * @return*     possible object is*     {@link Dessert }*     */public Dessert getDessert() {return dessert;}/*** Sets the value of the dessert property.* * @param value*     allowed object is*     {@link Dessert }*     */public void setDessert(Dessert value) {this.dessert = value;}}

具有特定的VegetableDessert类的优点是,与一般的Java String相比,它们具有附加的类型安全性。 Vegetable.javaDessert.java实际上都是枚举,因为它们来自XSD中的枚举值。 接下来的两个代码清单中显示了这两个生成的枚举。

Vegetable.java(使用JAXB xjc编译器生成)

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2015.02.11 at 10:17:32 PM MST
//package com.blogspot.marxsoftware.foodxml;import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlEnumValue;
import javax.xml.bind.annotation.XmlType;/*** <p>Java class for Vegetable.* * <p>The following schema fragment specifies the expected content contained within this class.* <p>* <pre>* <simpleType name="Vegetable">*   <restriction base="{http://www.w3.org/2001/XMLSchema}string">*     <enumeration value="Carrot"/>*     <enumeration value="Squash"/>*     <enumeration value="Spinach"/>*     <enumeration value="Celery"/>*   </restriction>* </simpleType>* </pre>* */
@XmlType(name = "Vegetable")
@XmlEnum
public enum Vegetable {@XmlEnumValue("Carrot")CARROT("Carrot"),@XmlEnumValue("Squash")SQUASH("Squash"),@XmlEnumValue("Spinach")SPINACH("Spinach"),@XmlEnumValue("Celery")CELERY("Celery");private final String value;Vegetable(String v) {value = v;}public String value() {return value;}public static Vegetable fromValue(String v) {for (Vegetable c: Vegetable.values()) {if (c.value.equals(v)) {return c;}}throw new IllegalArgumentException(v);}}

Dessert.java(使用JAXB xjc编译器生成)

//
// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802
// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
// Any modifications to this file will be lost upon recompilation of the source schema.
// Generated on: 2015.02.11 at 10:17:32 PM MST
//package com.blogspot.marxsoftware.foodxml;import javax.xml.bind.annotation.XmlEnum;
import javax.xml.bind.annotation.XmlEnumValue;
import javax.xml.bind.annotation.XmlType;/*** <p>Java class for Dessert.* * <p>The following schema fragment specifies the expected content contained within this class.* <p>* <pre>* <simpleType name="Dessert">*   <restriction base="{http://www.w3.org/2001/XMLSchema}string">*     <enumeration value="Pie"/>*     <enumeration value="Cake"/>*     <enumeration value="Ice Cream"/>*   </restriction>* </simpleType>* </pre>* */
@XmlType(name = "Dessert")
@XmlEnum
public enum Dessert {@XmlEnumValue("Pie")PIE("Pie"),@XmlEnumValue("Cake")CAKE("Cake"),@XmlEnumValue("Ice Cream")ICE_CREAM("Ice Cream");private final String value;Dessert(String v) {value = v;}public String value() {return value;}public static Dessert fromValue(String v) {for (Dessert c: Dessert.values()) {if (c.value.equals(v)) {return c;}}throw new IllegalArgumentException(v);}}

为XML元素生成枚举可确保只有这些元素的有效值才能用Java表示。

结论

JAXB使将Java映射到XML相对容易,但是由于Java和XML类型之间没有一对一的映射,因此在某些情况下,为特定XSD指定元素生成的Java类型并不明显。 这篇文章显示了两种不同的构建XSD来强制使用相同的基本XML结构的方法如何导致用JAXB xjc编译器生成的Java类产生截然不同的结果。 在本文中显示的示例中,由于类型安全,所以直接在simpleType上声明XSD中的元素以将XSD的string限制为一组特定的枚举值比将元素声明为对其他包装有受限制的字符串枚举值的simpleType的元素的引用更为可取这是在生成枚举而不是使用常规Java String的。

翻译自: https://www.javacodegeeks.com/2015/02/jaxb-nuance-string-versus-enum-enumerated-restricted-xsd-string.html

一个JAXB Nuance:字符串与枚举(受限制的XSD字符串)相关推荐

  1. jaxb解析字符串xml_一个JAXB Nuance:字符串与枚举(受限制的XSD字符串)的枚举

    jaxb解析字符串xml 尽管用于XML绑定的Java体系结构 ( JAXB )在名义情况下(尤其是自Java SE 6以来) 相当容易使用,但它也存在许多细微差别. 一些常见的细微差别是由于无法将 ...

  2. 把数据库中有关枚举项值的数字字符串转换成文字字符串

    原文:把数据库中有关枚举项值的数字字符串转换成文字字符串 标题可能无法表达我的本意.比如,有这样一个枚举: public enum MyChoice { MyFirstChoice = 0, MySe ...

  3. 枚举值转换(字符串转换为枚举和整数转换为枚举)

    假设定义了一个这样的枚举类型: enum MyEnum { aa = 1, bb = 2 } 1.字符串转换为枚举: string strA = "aa"; MyEnum myEn ...

  4. java枚举返回字符串_枚举工具类-通过给定值获取对应的枚举类

    开发背景: 在开发过程中遇到需要通过给定的值来获取对应的枚举值,如下例枚举类中,需要通过传入"春"来获取SPRING. public 开始尝试通过Enum的内置方法valueOf( ...

  5. c# 编程入门第六课常量,枚举,枚举转换成其他类型变量(枚举和int,转 string字符串转枚举),结构体,数组,冒泡排序,实际使用排序,方法(函数)

    c# 编程入门第六课 文章目录 c# 编程入门第六课 1. 常量 2. 枚举 3. 枚举转换成其他类型变量 3.1 枚举和int 3.2 转string 3.2 字符串转枚举 4.结构体 5.数组 7 ...

  6. LabVIEW数字、字符串转换为枚举型

    LabVIEW数字.字符串转换为枚举型 以利用LabVIEW 中的 Scan From String函数将字符串转换为枚举类型.下面是一个关于如何完成此操作的简单示例. 此函数区分大小写.如果输入的字 ...

  7. 输入一个字符串,用子函数完成在字符串中找出ACSII码值最大的字符,将其放在第一个位置,并将该字符前的所有字符向后顺序移动

    <程序设计基础实训指导教程-c语言> ISBN 978-7-03-032846-5 p143 7.1.2 上级实训内容 [实训内容9]输入一个字符串,用子函数完成在字符串中找出ACSII码 ...

  8. 算法-打印一个字符串的全部子序列,包括空字符串

    题目:打印一个字符串的全部子序列,包括空字符串 假如该字符串为"abc"则用画图的方式穷举所有可能 代码如下: public class PrintAllSubsquences { ...

  9. 枚举的遍历和字符串转枚举,枚举转字符串

    enum   mycity     {     beijing,shanghai     } 枚举的遍历   foreach(   mycity   city   in   enum.getvalue ...

最新文章

  1. SpringBoot直接访问图片资源
  2. ubuntu设置字体编码GBK和UTF-8
  3. 【Android 安装包优化】开启 ProGuard 混淆 ( 压缩 Shrink | 优化 Optimize | 混淆 Obfuscate | 预检 | 混淆文件编写 | 混淆前后对比 )
  4. 8.初探python之集合
  5. php bigpipe实现,如何通过php 实现BigPipe分块输出
  6. Eureka常用配置详解
  7. 发生地震等灾难,死难者的存款会怎么处理?
  8. leetcode1007. 行相等的最少多米诺旋转(贪心)
  9. MFC的Dialogbox多行文本框(CEdit)有最大字符限制,默认最大显示长度
  10. Spring MVC 入门基础(一)
  11. sublime text 3 php 语法错误检查
  12. win7系统计算机怎么更改密码,Win7系统怎么设置和删除电脑开机密码?
  13. linux编译libmp3lame,使用libmp3lame库编码mp3
  14. 论“GPL就是给软件开发者们准备的坑”
  15. 算法基础:快排优化:为什么快排都会TLE
  16. 孩子不是绑架婚姻的借口
  17. 小米再次回购股票:斥资近1亿港元 传递市场信心
  18. QT 图片浏览器(一)
  19. [渝粤教育] 广东-国家-开放大学 21秋期末考试大学英语210262k2 (2)
  20. CoffeeScript - CoffeeScript安装使用入门

热门文章

  1. 购物车的功能——CSS源码
  2. Servelt 中文乱码
  3. EasyExcel中输出为时间格式
  4. 2015蓝桥杯省赛---java---C---1(隔行变色)
  5. 联想linux笔记本评测,联想(lenovo)G460AL-ITH Linux笔记本电脑CPU测试评测-ZOL中关村在线...
  6. hashmap存多少条数据_干货 | 面试官想问的HashMap,都在这一篇里面了!
  7. java 招聘要求_Java程序员如何进阶,一般招聘都有哪些要求?
  8. rpa文件怎么提取内容_怎么编辑pdf文件内容?有什么软件可以编辑pdf文件吗?
  9. 收敛和发散思维如何被用作解决问题的手段
  10. DevExperience(1712)