分享
 
 
 

从XML到Java代码的数据绑定之二

王朝java/jsp·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

数据绑定系列的第二篇是如何从 XML 数据限制中生成一个 Java 语言。本文通过完整的代码展现了如何生成类和代码,并提供了如何定制您自己版本的建议。还没有看过第一篇吗?第一篇,"对象,无处不在的对象", 解释了数据绑定是如何将 XML 和 Java 语言对象互为转换。它比较了数据绑定和其它在 Java 程序中处理 XML 的方法, 并介绍了一个 XML 配置文档示例。第一部分也介绍了使用 XML Schema 来约束数据。

在深入 Java 程序和 XML 代码之前,先快速回顾一下本系列第一部分所打下的基础。

在第一部分中,我们知道只要可以标识文档的一组约束,就可以将文档转换成 Java 对象。那些约束为数据提供了接口。如 Web 服务配置文档示例中所示,XML 文档应当成为现有 Java 类的一个实例,并且从数据约束生成那个类。最后,会看到表示样本 XML 文档约束的 XML schema。

如果对细节还有疑问,请回顾第一篇文章.

打造基础

现在,可以着手从 XML schema 创建 Java 类。该类必须准确表示数据约束,并提供 Java 应用程序将使用的简单读方法和写方法。开始之前,让我们先回顾清单 1,查看为 WebServiceConfiguration 文档定义的 XML schema。

清单 1. 表示 Web 容器配置文档数据接口的 XML schema

<?xml version="1.0"?>

<schema targetNamespace="http://www.enhydra.org"

xmlns="http://www.w3.org/1999/xmlSchema"

xmlns:enhydra="http://www.enhydra.org"

<complexType name="ServiceConfiguration">

<attribute name="name" type="string" />

<attribute name="version" type="float" />

</complexType>

<element name="serviceConfiguration" type="ServiceConfiguration" />

<complexType name="WebServiceConfiguration"

baseType="ServiceConfiguration"

derivedBy="extension">

<element name="port">

<complexType>

<attribute name="protocol" type="string" />

<attribute name="number" type="integer" />

<attribute name="protected" type="string" />

</complexType>

</element>

<element name="document">

<complexType>

<attribute name="root" type="string" />

<attribute name="index" type="string" />

<attribute name="error" type="string" />

</complexType>

</element>

</complexType>

<element name="webServiceConfiguration" type="WebServiceConfiguration" />

</schema>

生成代码

开始生成 Java 代码之前,首先必须确定核心类的名称。将使用 org.enhydra.xml.binding 包中的 SchemaMapper,它是 Enhydra 应用服务器实用程序类集合的一部分。还可以将任何必需的支持类放到这个包中。

除了类名称以外,还必须确定用来读取和创建 XML 的 Java API。如上一篇文章中所讨论过的,三种主要选择是 SAX、DOM 和 JDOM。由于 SAX 仅仅适用于读取 XML 文档,因此它不适合创建 XML。由于在打包阶段中要将 Java 对象转换为 XML 表示,因此在此阶段中需要创建 XML。这就将选择的范围缩小到 DOM 和 JDOM。在这两种选择都可用的情况下,本例中我选择使用 JDOM API,仅为了显示其功能性(并不仅仅因为我是它的合著者之一!)。

最后,必须指出如何将 XML schema 提供给 SchemaMapper 类。通常,可以假设类的生成是脱机完成的(通过静态 main 方法)。仅通过使 main 方法调用非静态方法,还可以从运行时环境中使用类。做了这些决定后,就可以开始勾画类的框架了。

组装 SchemaMapper 类框架

要做的第一件事就是为要生成的代码设置一些基本存储器。必须能够从每个执行映射的 XML schema 生成多个接口和实现。Java HashMap 正好满足要求。键是接口或实现名称以及映射表中的值,该值是将要输出到新 Java 程序文件的实际代码。还需要存储每对接口/实现的属性(属性是在这两种类之间共享的)。这里,我再次使用 HashMap。其中,键是接口名称。但是,由于每个接口可能有多个属性,因此该值是另一个具有属性及其类型的 HashMap。最后,必须存储 XML schema 的名称空间,因为 JDOM 将使用这个名称空间来访问 XML schema 中的结构。所有这些具体信息都足以初步勾画出新类的框架,新类在清单 2 中。

还请注意在清单 2 中已添加了两个需要使用的基本方法:其中一个方法需要使用 XML schema 的 URL 来执行生成(允许它在网络可访问 schema 以及本地 schema 下运行),另一个方法将类输出到指定的目录中。最后,简单的 main 方法将 XML schema 看作一个变量,然后执行生成。

清单 2. SchemaMapper 类的框架 package org.enhydra.xml.binding;

import java.io.File;

import java.io.FileNotFoundException;

import java.io.FileWriter;

import java.io.IOException;

import java.net.URL;

import java.util.HashMap;

import java.util.Map;

import java.util.Iterator;

import java.util.List;

// JDOM classes used for document representation

import org.jdom.Document;

import org.jdom.Element;

import org.jdom.JDOMException;

import org.jdom.Namespace;

import org.jdom.NoSuchAttributeException;

import org.jdom.NoSuchChildException;

import org.jdom.input.SAXBuilder;

/**

* <p>

* <code>SchemaMapper</code> handles generation of Java interfaces and classes

* from an XML schema, essentially allowing data contracts to be set up

* for the binding of XML instance documents to Java objects.

* </p>

*

* @author Brett McLaughlin

*/

public class SchemaMapper {

/** Storage for code for interfaces */

private Map interfaces;

/** Storage for code for implementations */

private Map implementations;

/** Properties that accessor/mutators should be created for */

protected Map properties;

/** XML Schema Namespace */

private Namespace schemaNamespace;

/** XML Schema Namespace URI */

private static final String SCHEMA_NAMESPACE_URI =

"http://www.w3.org/1999/xmlSchema";

/**

* <p>

* Allocate storage and set up defaults.

* </p>

*/

public SchemaMapper() {

interfaces = new HashMap();

implementations = new HashMap();

properties = new HashMap();

schemaNamespace = Namespace.getNamespace(SCHEMA_NAMESPACE_URI);

}

/**

* <p>

* This is the "entry point" for generation of Java classes from an XML

* Schema. It allows a schema to be supplied, via <code>URL</code>,

* and that schema is used for input to generation.

* </p>

*

* @param schemaURL <code>URL</code> at which XML Schema is located.

* @throws <code>IOException</code> - when problems in generation occur.

*/

public void generateClasses(URL schemaURL) throws IOException {

// Perform generation

}

/**

* <p>

* This will write out the generated classes to the supplied stream.

* </p>

*

* @param directory <code>File</code> to write to (should be a directory).

* @throws <code>IOException</code> - when output errors occur.

*/

public void writeClasses(File dir) throws IOException {

// Perform output to files

}

/**

* <p>

* This provides a static entry point for class generation from

* XML Schemas.

* </p>

*

* @param args <code>String[]</code> list of files to parse.

*/

public static void main(String[] args) {

SchemaMapper mapper = new SchemaMapper();

try {

for (int i=0; i<args.length; i++) {

File file = new File(args[i]);

mapper.generateClasses(file.toURL());

mapper.writeClasses(new File("."));

}

} catch (FileNotFoundException e) {

System.out.println("Could not locate XML Schema: ");

e.printStackTrace();

} catch (IOException e) {

System.out.println("Java class generation failed: ");

e.printStackTrace();

}

}

}

In 清单 2 中,可以看到对于每个作为自变量传递的 XML schema,main

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有