XML 模式是 XML 文档结构基于 XML 的表示。很多 J2EE 开发人员都使用 XML 模式来而非文档类型定义 (DTD) 来生成 XML 文档,这是因为,与 DTD 不同,XML 模式支持多种数据类型和命名空间。
人们经常会需要一个基于 XML 模式的 XML 文档。例如,您可能会发现自己需要一个基于企业 JavaBeans 部署描述符架构 (ejb-jar_2_1.xsd) 的 XML 文档。
包含在 用于 Java 的 Oracle 10 g XML 开发人员工具包 (XDK) 产品版 ( 下载 )中的 JAXB 类生成器是一个用于从 XML 模式生成 Java 类的编译器。(可以使用 Oracle JDeveloper 10 g XML 模式编辑器 构建 XML 模式。)JAXB 类生成器代替了 Oracle9 i XDK 中的模式类生成器,它生成表示 XML 模式中各种元素和 complexType 声明的 Java 类。( 用于 XML 绑定的 Java 体系结构 ,即 JAXB,是一种用于将 XML 模式绑定到 Java 代码表示的技术。)然后,J2EE 开发人员就可以使用 JAXB 类生成器生成的 Java 类来构建符合 XML 模式的 XML 文档了。
在本技术说明中,我们将使用 JAXB 类生成器从一个示例 XML 模式生成 Java 类。然后,我们将从这些 Java 类创建一个示例 XML 文档。
预备设置 (Windows)
要使用 JAXB 类生成器从 XML 模式生成 Java 类,Oracle 10 g XDK JAXB 类生成器类以及命令行实用程序 orajaxb 必须加入类路径 (Classpath) 中。将 xdk_nt_10_1_0_2_0_production.zip 文件解压缩到安装目录。将
1<xdk>/lib/xml.jar、<xdk>/lib/xmlparserv2.jar 和 <xdk>/lib/xmlmesg.jar 添加到 Classpath 变量。<xdk> 是 Oracle 10 _g_ XDK 产品版所安装在的目录。
2
3用于生成 Java 类的 XML 模式
4
5JAXB 类生成器会生成与顶级元素和顶级 complexType 元素相对应的 Java 类。在 XML 模式中,元素使用 ` <xs:element> ` 表示,complexType 则使用 ` <xs:complextype> ` 表示。
6
7下面是一个 XML 模式示例,OracleCatalog.xsd,该模式由一些顶级元素和顶级 complexType 元素组成:
8
9
10 <xs:schema elementformdefault="qualified" targetnamespace="http://jaxbderived/catalog" xmlns:catalog="http://jaxbderived/catalog" xmlns:xs="http://www.w3.org/2001/XMLSchema">
11<xs:element name="OracleCatalog" type="catalog:catalog"></xs:element>
12<xs:complextype name="catalog">
13<xs:sequence>
14<xs:element maxoccurs="unbounded" minoccurs="0" name="journal" type="catalog:journal"></xs:element>
15</xs:sequence>
16<xs:attribute name="title" type="xs:string"></xs:attribute>
17<xs:attribute name="publisher" type="xs:string"></xs:attribute>
18</xs:complextype>
19<xs:complextype name="journal">
20<xs:sequence>
21<xs:element maxoccurs="unbounded" minoccurs="0" name="article" type="catalog:article"></xs:element>
22</xs:sequence>
23<xs:attribute name="date" type="xs:string"></xs:attribute>
24</xs:complextype>
25<xs:complextype name="article">
26<xs:sequence>
27<xs:element name="title" type="xs:string"></xs:element>
28<xs:element maxoccurs="unbounded" minoccurs="0" name="author" type="xs:string"></xs:element>
29</xs:sequence>
30<xs:attribute name="section" type="xs:string"></xs:attribute>
31</xs:complextype>
32</xs:schema>
33
34
35生成 Java 类
36
37在本节中,我们将讲述从 OracleCatalog.xsd 生成 Java 类的过程。正如前面所提到的那样,Java 类是使用 JAXB 类生成器命令行界面 orajaxb 生成的:
38
39
40 >java oracle.xml.jaxb.orajaxb -schema OracleCatalog.xsd -outputDir classes
41
42
43以下是 orajaxb 的一些选项:
44
45 * ` outputDir <dir> ` 指定在其中生成 Java 类的目录。
46 * ` schema <schemafile> ` 指定从中生成 Java 类的 XML 模式。
47 * ` targetPkg <targetpkg> ` 指定目标程序包名称。
48
49在我们的示例中,将生成的 Java 类为:Article.java、ArticleImpl.java、OracleCatalog.java、OracleCatalogImpl.java、Catalog.java、CatalogImpl.java、Journal.java、JournaImpl.java 和 ObjectFactory.java。(根据生成这些类所用的 XDK 版本的不同,所生成的 Java 类可能会有所不同,但是这些类的实现是相同的。)对应于该示例 XML 模式中的每个顶级元素和顶级 complexType 生成 Java 接口和 Java 类。还会生成 ObjectFactory.java 类,该类由用于创建接口对象的一些方法组成,如下所示:
50
51
52 package jaxbderived.catalog;
53
54 public class ObjectFactory
55 {
56 public jaxbderived.catalog.Journal createJournal()
57 {
58 jaxbderived.catalog.Journal elem = new jaxbderived.catalog.JournalImpl(ownerDocument);
59 return elem;
60 }
61
62 public jaxbderived.catalog.Article createArticle()
63 {
64 jaxbderived.catalog.Article elem = new jaxbderived.catalog.ArticleImpl(ownerDocument);
65 return elem;
66 }
67
68 public jaxbderived.catalog.Catalog createCatalog()
69 {
70 jaxbderived.catalog.Catalog elem = new jaxbderived.catalog.CatalogImpl(ownerDocument);
71 return elem;
72 }
73
74 public jaxbderived.catalog.OracleCatalog createOracleCatalog()
75 {
76 jaxbderived.catalog.OracleCatalog elem = new jaxbderived.catalog.OracleCatalogImpl(ownerDocument);
77 return elem;
78 }
79
80 public Object newInstance (Class javaContentInterface) throws javax.xml.bind.JAXBException
81 {
82 Object newInstance = null;
83 String elemName = javaContentInterface.getName();
84 try
85 {
86 if (elemName.equals("jaxbderived.catalog.OracleCatalog"))
87 {
88 newInstance = new jaxbderived.catalog.OracleCatalogImpl(ownerDocument);
89 return newInstance;
90 }
91 }
92 catch (Exception e)
93 {
94 throw new javax.xml.bind.JAXBException(e.toString());
95 }
96 return null;
97 }
98
99 public Object getProperty(String name)
100 {
101 return null;
102 }
103
104 public void setProperty(String name, Object value)
105 {
106 }
107
108 public Object unmarshal(org.w3c.dom.Node node) throws javax.xml.bind.UnmarshalException
109 {
110 String elemName = node.getLocalName();
111 try
112 {
113 if (elemName.equals("OracleCatalog"))
114 {
115 jaxbderived.catalog.OracleCatalog unode =
116 new jaxbderived.catalog.OracleCatalogImpl((oracle.xml.parser.v2.XMLElement)node);
117 return unode;
118 }
119 }
120 catch (Exception e)
121 {
122 throw new javax.xml.bind.UnmarshalException(e.toString());
123 }
124 return null;
125 }
126
127 private oracle.xml.parser.v2.XMLDocument ownerDocument =
128 new oracle.xml.parser.v2.XMLDocument();
129
130 }
131
132
133
134OracleCatalog.java 是使用 JAXB 类生成器生成的、对应于 XML 模式中顶级元素的 Java 类之一,它是对应于 OracleCatalog.xsd 模式中顶级元素 ` OracleCatalog ` 而生成的 Java 接口。
135
136
137 package jaxbderived.catalog;
138
139 public interface OracleCatalog extends jaxbderived.catalog.Catalog, javax.xml.bind.Element
140 {
141 }
142
143
144OracleCatalogImpl.java 是对应于 OracleCatalog.xsd 模式顶级元素 ` OracleCatalog ` 而生成的 Java 类:
145
146
147 package jaxbderived.catalog;
148
149 public class OracleCatalogImpl extends jaxbderived.catalog.CatalogImpl implements jaxbderived.catalog.OracleCatalog
150 {
151 public OracleCatalogImpl(oracle.xml.parser.v2.XMLDocument ownerDoc)
152 {
153 super("OracleCatalog", "http://jaxbderived/catalog", ownerDoc);
154 }
155
156 public OracleCatalogImpl(String name, String namespace, oracle.xml.parser.v2.XMLDocument ownerDoc)
157 {
158 super(name, namespace, ownerDoc);
159 }
160
161 public OracleCatalogImpl(oracle.xml.parser.v2.XMLElement node)
162 {
163 super(node);
164 }
165
166 }
167
168
169Catalog.java 是对应于 XML 模式中顶级 complexType 声明生成的 Java 类之一,它是对应于 OracleCatalog.xsd 模式顶级 complexType ` catalog ` 而生成的 Java 接口。
170
171
172 package jaxbderived.catalog;
173
174 public interface Catalog
175 {
176 public void setTitle(java.lang.String t);
177
178 public java.lang.String getTitle();
179
180 public void setPublisher(java.lang.String p);
181
182 public java.lang.String getPublisher();
183
184 public java.util.List getJournal();
185
186 }
187
188
189CatalogImpl.java 是对应于顶级模式 complexType ` catalog ` 而生成的 Java 类:
190
191
192 package jaxbderived.catalog;
193
194 public class CatalogImpl extends oracle.xml.jaxb.JaxbNode implements jaxbderived.catalog.Catalog
195 {
196 public CatalogImpl(oracle.xml.parser.v2.XMLDocument ownerDoc)
197 {
198 super("catalog", "http://jaxbderived/catalog", ownerDoc);
199 }
200
201 public CatalogImpl(String name, String namespace, oracle.xml.parser.v2.XMLDocument ownerDoc)
202 {
203 super(name, namespace, ownerDoc);
204 }
205
206 public CatalogImpl(oracle.xml.parser.v2.XMLElement node)
207 {
208 super(node);
209 }
210
211 public void setTitle(java.lang.String t)
212 {
213 super.setJaxbAttrStringValue("title", "", t);
214 }
215
216 public java.lang.String getTitle()
217 {
218 return super.getJaxbAttrStringValue("title", "");
219 }
220
221 public void setPublisher(java.lang.String p)
222 {
223 super.setJaxbAttrStringValue("publisher", "", p);
224 }
225
226 public java.lang.String getPublisher()
227 {
228 return super.getJaxbAttrStringValue("publisher", "");
229 }
230
231 public java.util.List getJournal()
232 {
233 return (java.util.List)super.getList("journal", "http://jaxbderived/catalog", this, 0);
234 }
235
236 public Object createJaxbNode(oracle.xml.parser.v2.XMLNode node)
237 {
238 String name = node.getLocalName();
239 String namespace = node.getNamespaceURI();
240 if (namespace == null)
241 namespace = "";
242
243 if (name.equals("journal") && namespace.equals("http://jaxbderived/catalog"))
244 {
245 jaxbderived.catalog.JournalImpl obj = new jaxbderived.catalog.JournalImpl(getOwnerDocument());
246 obj.populateNodeArray(node);
247 return obj;
248 }
249
250 return null;
251 }
252
253 public void populateNodeArray(oracle.xml.parser.v2.XMLNode node)
254 {
255 String name, namespace;
256 oracle.xml.parser.v2.XMLNode n = (oracle.xml.parser.v2.XMLNode)node.getFirstChild();
257
258 while (n != null)
259 {
260 name = n.getLocalName();
261 namespace = n.getNamespaceURI();
262
263 if (namespace == null)
264 namespace = "";
265
266 if (name.equals("journal") && namespace.equals("http://jaxbderived/catalog"))
267 {
268 super.setNodeVectorValue(0, n);
269 }
270
271 n = (oracle.xml.parser.v2.XMLNode)n.getNextSibling();
272 }
273
274 super.populateNodeArray(node);
275 }
276
277 static final Object[] _Journal =
278 {};
279
280 static final Object[] _Catalog =
281 {_Journal };
282
283 protected Object[] getSchemaObject()
284 {
285 return _Catalog;
286 }
287
288 }
289
290
291
292现在,我们来继续介绍从这些 Java 类生成 XML 文档的过程。
293
294创建 XML 文档
295
296在本节中,我们将从使用 JAXB 类生成器生成的上面这些 Java 类创建一个 XML 文档示例,OracleCatalog.xml。
297
298从这些 Java 类创建 ` CatalogImpl ` ,并对 ` CatalogImpl ` 类对象进行编组,以构建一个 XML 文档。首先,导入 javax.xml.bind 程序包。
299
300
301 import javax.xml.bind.*;
302
303
304现在导入这些 Oracle JAXB 类。
305
306
307 import oracle.xml.jaxb.*;
308
309
310创建一个编组器将 ` catalog ` 对象编组到 XML 文档中。
311
312
313 JaxbContextImpl jaxbContext=new JaxbContextImpl();
314 Marshaller marshaller=jaxbContext.createMarshaller();
315
316
317现在,创建 ` ObjectFactory ` ,我们将从中创建一个实现类的新实例。 ` ObjectFactory ` 是 JAXB 的一个重要特性,因为它提供代码可移植性。
318
319
320 ObjectFactory factory=new ObjectFactory();
321
322
323创建 ` catalog ` 元素:
324
325
326 CatalogImpl catalog=(CatalogImpl)(factory.createCatalog());
327
328
329设置 ` catalog ` 元素的 title 属性:
330
331
332 catalog.setTitle("Oracle Magazine");
333
334
335设置 catalog 元素的 publisher 属性。
336
337
338 catalog.setPublisher("Oracle Publishing");
339
340
341创建 ` journal ` 元素。
342
343
344 JournalImpl journal=(JournalImpl)(factory.createJournal());
345
346
347设置 ` journal ` 元素的 date 属性。
348
349
350 journal.setDate("November-December 2003");
351
352
353将 ` journal ` 元素添加到 ` catalog ` 元素。
354
355
356 java.util.List journalList=catalog.getJournal();
357 journalList.add(journal);
358
359
360在 ` journal ` 元素中创建 ` article ` 元素。
361
362
363 ArticleImpl article=(ArticleImpl)(factory.createArticle());
364
365
366设置 ` article ` 元素的 section 属性。
367
368
369 article.setSection("XML");
370
371
372在 ` article ` 元素中创建 ` title ` 元素。
373
374
375 article.setTitle("Updating XQuery");
376
377
378向 ` journal ` 元素添加 ` article ` 元素。
379
380
381 java.util.List articleList=journal.getArticle();
382 articleList.add(article);
383
384
385在 ` article ` 元素中创建 ` author ` 元素。
386
387
388 java.util.List authorList=article.getAuthor();
389 authorList.add("Jason Hunter");
390
391
392与使用上面说明的步骤创建的 ` journal ` 元素相似,添加另外一个 ` journal ` 元素,以创建示例 XML 文档 OracleCatalog.xml。然后将 CatalogImpl 对象编组到一个 XML 文档。
393
394
395 marshaller.marshal(catalog, new FileOutputStream(xmlDocument));
396
397
398这就生成了 OracleCatalog.xml:
399
400
401 <?xml version="1.0" encoding = 'UTF-8'?>
402<catalog publisher="Oracle Publishing" title="Oracle Magazine" xmlns="http://jaxbderived/catalog">
403<journal date="November-December 2003">
404<article section="XML">
405<title>Updating XQuery</title>
406<author>Jason Hunter</author>
407</article>
408</journal>
409<journal date="September-October 2003">
410<article section="SQL">
411<title>The Active Database</title>
412<author> Cameron ORourke</author>
413</article>
414</journal>
415</catalog>
416
417
418下面所示为 XMLConstructor.java,它是用于从这些 Java 类创建 XML 文档的程序:
419
420
421 import jaxbderived.catalog.*;
422 import oracle.xml.jaxb.*;
423 import oracle.xml.parser.v2.*;
424 import java.io.File;
425 import java.io.FileOutputStream;
426 import java.io.IOException;
427 import javax.xml.bind.*;
428
429 public class XMLConstructor
430 {
431 public void generateXMLDocument(File xmlDocument){
432 try
433 {
434
435 JaxbContextImpl jaxbContext=new JaxbContextImpl();
436 Marshaller marshaller=jaxbContext.createMarshaller();
437
438
439 ObjectFactory factory=new ObjectFactory();
440 CatalogImpl catalog=(CatalogImpl)(factory.createCatalog());
441 catalog.setTitle("Oracle Magazine");
442 catalog.setPublisher("Oracle Publishing");
443
444
445 JournalImpl journal=(JournalImpl)(factory.createJournal());
446 journal.setDate("November-December 2003");
447
448
449
450 ArticleImpl article=(ArticleImpl)(factory.createArticle());
451
452 article.setSection("XML");
453 article.setTitle("Updating XQuery");
454
455
456
457 java.util.List journalList=catalog.getJournal();
458
459 journalList.add(journal);
460
461 java.util.List articleList=journal.getArticle();
462
463 articleList.add(article);
464
465 java.util.List authorList=article.getAuthor();
466 authorList.add("Jason Hunter");
467
468
469 journal=(JournalImpl)(factory.createJournal());
470 journal.setDate("September-October 2003");
471
472
473 article=(ArticleImpl)(factory.createArticle());
474
475 article.setSection("SQL");
476 article.setTitle("The Active Database");
477
478
479 journalList=catalog.getJournal();
480
481 journalList.add(journal);
482
483 articleList=journal.getArticle();
484
485 articleList.add(article);
486
487 authorList=article.getAuthor();
488 authorList.add("Cameron ORourke");
489
490 marshaller.marshal(catalog, new FileOutputStream(xmlDocument));
491
492 }catch (IOException e)
493 {
494 System.out.println(e.toString());
495
496 }
497 catch (JAXBException e)
498 {
499 System.out.println(e.toString());
500
501 }
502
503 }
504 public static void main (String[] argv)
505 { String xmlDocument=argv[0];
506 XMLConstructor xmlConstructor=new XMLConstructor();
507 xmlConstructor.generateXMLDocument(new File(xmlDocument));
508 }
509 }
510
511
512恭喜!您已经通过 JAXB 生成了 Java 类,然后使用这些类从 XML 模式构建了一个 XML 文档。</targetpkg></schemafile></dir></xs:complextype></xs:element></xdk></xdk></xdk></xdk>