利用JAXB通過XML模式生成XML文檔

XML 模式是 XML 文檔結構基於 XML 的表示。很多 J2EE 開發人員都使用 XML 模式來而非文檔類型定義 (DTD) 來生成 XML 文檔,這是因爲,與 DTD 不同,XML 模式支持多種數據類型和命名空間。


人們經常會需要一個基於 XML 模式的 XML 文檔。例如,您可能會發現自己需要一個基於企業 JavaBeans 部署描述符架構 (ejb-jar_2_1.xsd) 的 XML 文檔。

包含在用於 Java 的 Oracle 10g XML 開發人員工具包 (XDK) 產品版(下載)中的 JAXB 類生成器是一個用於從 XML 模式生成 Java 類的編譯器。(可以使用 Oracle JDeveloper 10g XML 模式編輯器構建 XML 模式。)JAXB 類生成器代替了 Oracle9i XDK 中的模式類生成器,它生成表示 XML 模式中各種元素和 complexType 聲明的 Java 類。(用於 XML 綁定的 Java 體系結構,即 JAXB,是一種用於將 XML 模式綁定到 Java 代碼表示的技術。)然後,J2EE 開發人員就可以使用 JAXB 類生成器生成的 Java 類來構建符合 XML 模式的 XML 文檔了。

在本技術說明中,我們將使用 JAXB 類生成器從一個示例 XML 模式生成 Java 類。然後,我們將從這些 Java 類創建一個示例 XML 文檔。

預備設置 (Windows)


要使用 JAXB 類生成器從 XML 模式生成 Java 類,Oracle 10g XDK JAXB 類生成器類以及命令行實用程序 orajaxb 必須加入類路徑 (Classpath) 中。將 xdk_nt_10_1_0_2_0_production.zip 文件解壓縮到安裝目錄。將 <XDK>/lib/xml.jar、<XDK>/lib/xmlparserv2.jar 和 <XDK>/lib/xmlmesg.jar 添加到 Classpath 變量。<XDK> 是 Oracle 10g XDK 產品版所安裝在的目錄。

用於生成 Java 類的 XML 模式


JAXB 類生成器會生成與頂級元素和頂級 complexType 元素相對應的 Java 類。在 XML 模式中,元素使用 <xs:element> 表示,complexType 則使用 <xs:complexType> 表示。

下面是一個 XML 模式示例,OracleCatalog.xsd,該模式由一些頂級元素和頂級 complexType 元素組成:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://jaxbderived/catalog"
xmlns:catalog="http://jaxbderived/catalog"
elementFormDefault="qualified">

<xs:element name="OracleCatalog" type="catalog:catalog"/>

<xs:complexType name="catalog">
<xs:sequence>
<xs:element name="journal" type="catalog:journal" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="title" type="xs:string"/>
<xs:attribute name="publisher" type="xs:string"/>
</xs:complexType>

<xs:complexType name="journal">
<xs:sequence>
<xs:element name="article" type="catalog:article" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="date" type="xs:string"/>
</xs:complexType>
<xs:complexType name="article">
<xs:sequence>
<xs:element name="title" type="xs:string"/>
<xs:element name="author" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="section" type="xs:string"/>
</xs:complexType>
</xs:schema>

生成 Java 類

在本節中,我們將講述從 OracleCatalog.xsd 生成 Java 類的過程。正如前面所提到的那樣,Java 類是使用 JAXB 類生成器命令行界面 orajaxb 生成的:
>java oracle.xml.jaxb.orajaxb -schema OracleCatalog.xsd -outputDir classes

以下是 orajaxb 的一些選項:
outputDir <dir> 指定在其中生成 Java 類的目錄。
schema <schemaFile> 指定從中生成 Java 類的 XML 模式。
targetPkg <targetPkg> 指定目標程序包名稱。
在我們的示例中,將生成的 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 類,該類由用於創建接口對象的一些方法組成,如下所示:
package jaxbderived.catalog;

public class ObjectFactory
{
public jaxbderived.catalog.Journal createJournal()
{
jaxbderived.catalog.Journal elem = new jaxbderived.catalog.JournalImpl(ownerDocument);
return elem;
}

public jaxbderived.catalog.Article createArticle()
{
jaxbderived.catalog.Article elem = new jaxbderived.catalog.ArticleImpl(ownerDocument);
return elem;
}

public jaxbderived.catalog.Catalog createCatalog()
{
jaxbderived.catalog.Catalog elem = new jaxbderived.catalog.CatalogImpl(ownerDocument);
return elem;
}

public jaxbderived.catalog.OracleCatalog createOracleCatalog()
{
jaxbderived.catalog.OracleCatalog elem = new jaxbderived.catalog.OracleCatalogImpl(ownerDocument);
return elem;
}

public Object newInstance (Class javaContentInterface) throws javax.xml.bind.JAXBException
{
Object newInstance = null;
String elemName = javaContentInterface.getName();
try
{
if (elemName.equals("jaxbderived.catalog.OracleCatalog"))
{
newInstance = new jaxbderived.catalog.OracleCatalogImpl(ownerDocument);
return newInstance;
}
}
catch (Exception e)
{
throw new javax.xml.bind.JAXBException(e.toString());
}
return null;
}

public Object getProperty(String name)
{
return null;
}

public void setProperty(String name, Object value)
{
}

public Object unmarshal(org.w3c.dom.Node node) throws javax.xml.bind.UnmarshalException
{
String elemName = node.getLocalName();
try
{
if (elemName.equals("OracleCatalog"))
{
jaxbderived.catalog.OracleCatalog unode =
new jaxbderived.catalog.OracleCatalogImpl((oracle.xml.parser.v2.XMLElement)node);
return unode;
}
}
catch (Exception e)
{
throw new javax.xml.bind.UnmarshalException(e.toString());
}
return null;
}

private oracle.xml.parser.v2.XMLDocument ownerDocument =
new oracle.xml.parser.v2.XMLDocument();

}


OracleCatalog.java 是使用 JAXB 類生成器生成的、對應於 XML 模式中頂級元素的 Java 類之一,它是對應於 OracleCatalog.xsd 模式中頂級元素 OracleCatalog 而生成的 Java 接口。
package jaxbderived.catalog;

public interface OracleCatalog extends jaxbderived.catalog.Catalog, javax.xml.bind.Element
{
}

OracleCatalogImpl.java 是對應於 OracleCatalog.xsd 模式頂級元素 OracleCatalog 而生成的 Java 類:
package jaxbderived.catalog;

public class OracleCatalogImpl extends jaxbderived.catalog.CatalogImpl implements jaxbderived.catalog.OracleCatalog
{
public OracleCatalogImpl(oracle.xml.parser.v2.XMLDocument ownerDoc)
{
super("OracleCatalog", "http://jaxbderived/catalog", ownerDoc);
}

public OracleCatalogImpl(String name, String namespace, oracle.xml.parser.v2.XMLDocument ownerDoc)
{
super(name, namespace, ownerDoc);
}

public OracleCatalogImpl(oracle.xml.parser.v2.XMLElement node)
{
super(node);
}

}

Catalog.java 是對應於 XML 模式中頂級 complexType 聲明生成的 Java 類之一,它是對應於 OracleCatalog.xsd 模式頂級 complexType catalog 而生成的 Java 接口。
package jaxbderived.catalog;

public interface Catalog
{
public void setTitle(java.lang.String t);

public java.lang.String getTitle();

public void setPublisher(java.lang.String p);

public java.lang.String getPublisher();

public java.util.List getJournal();

}

CatalogImpl.java 是對應於頂級模式 complexType catalog 而生成的 Java 類:
package jaxbderived.catalog;

public class CatalogImpl extends oracle.xml.jaxb.JaxbNode implements jaxbderived.catalog.Catalog
{
public CatalogImpl(oracle.xml.parser.v2.XMLDocument ownerDoc)
{
super("catalog", "http://jaxbderived/catalog", ownerDoc);
}

public CatalogImpl(String name, String namespace, oracle.xml.parser.v2.XMLDocument ownerDoc)
{
super(name, namespace, ownerDoc);
}

public CatalogImpl(oracle.xml.parser.v2.XMLElement node)
{
super(node);
}

public void setTitle(java.lang.String t)
{
super.setJaxbAttrStringValue("title", "", t);
}

public java.lang.String getTitle()
{
return super.getJaxbAttrStringValue("title", "");
}

public void setPublisher(java.lang.String p)
{
super.setJaxbAttrStringValue("publisher", "", p);
}

public java.lang.String getPublisher()
{
return super.getJaxbAttrStringValue("publisher", "");
}

public java.util.List getJournal()
{
return (java.util.List)super.getList("journal", "http://jaxbderived/catalog", this, 0);
}

public Object createJaxbNode(oracle.xml.parser.v2.XMLNode node)
{
String name = node.getLocalName();
String namespace = node.getNamespaceURI();
if (namespace == null)
namespace = "";

if (name.equals("journal") && namespace.equals("http://jaxbderived/catalog"))
{
jaxbderived.catalog.JournalImpl obj = new jaxbderived.catalog.JournalImpl(getOwnerDocument());
obj.populateNodeArray(node);
return obj;
}

return null;
}

public void populateNodeArray(oracle.xml.parser.v2.XMLNode node)
{
String name, namespace;
oracle.xml.parser.v2.XMLNode n = (oracle.xml.parser.v2.XMLNode)node.getFirstChild();

while (n != null)
{
name = n.getLocalName();
namespace = n.getNamespaceURI();

if (namespace == null)
namespace = "";

if (name.equals("journal") && namespace.equals("http://jaxbderived/catalog"))
{
super.setNodeVectorValue(0, n);
}

n = (oracle.xml.parser.v2.XMLNode)n.getNextSibling();
}

super.populateNodeArray(node);
}

static final Object[] _Journal =
{};

static final Object[] _Catalog =
{_Journal };

protected Object[] getSchemaObject()
{
return _Catalog;
}

}


現在,我們來繼續介紹從這些 Java 類生成 XML 文檔的過程。

創建 XML 文檔

在本節中,我們將從使用 JAXB 類生成器生成的上面這些 Java 類創建一個 XML 文檔示例,OracleCatalog.xml。

從這些 Java 類創建 CatalogImpl,並對 CatalogImpl 類對象進行編組,以構建一個 XML 文檔。首先,導入 javax.xml.bind 程序包。
import javax.xml.bind.*;

現在導入這些 Oracle JAXB 類。
import oracle.xml.jaxb.*;

創建一個編組器將 catalog 對象編組到 XML 文檔中。
JaxbContextImpl jaxbContext=new JaxbContextImpl();
Marshaller marshaller=jaxbContext.createMarshaller();

現在,創建 ObjectFactory,我們將從中創建一個實現類的新實例。ObjectFactory 是 JAXB 的一個重要特性,因爲它提供代碼可移植性。
ObjectFactory factory=new ObjectFactory();

創建 catalog 元素:
CatalogImpl catalog=(CatalogImpl)(factory.createCatalog());

設置 catalog 元素的 title 屬性:
catalog.setTitle("Oracle Magazine");

設置 catalog 元素的 publisher 屬性。
catalog.setPublisher("Oracle Publishing");

創建 journal 元素。
JournalImpl journal=(JournalImpl)(factory.createJournal());

設置 journal 元素的 date 屬性。
journal.setDate("November-December 2003");

將 journal 元素添加到 catalog 元素。
java.util.List journalList=catalog.getJournal();
journalList.add(journal);

在 journal 元素中創建 article 元素。
ArticleImpl article=(ArticleImpl)(factory.createArticle());

設置 article 元素的 section 屬性。
article.setSection("XML");

在 article 元素中創建 title 元素。
article.setTitle("Updating XQuery");

向 journal 元素添加 article 元素。
java.util.List articleList=journal.getArticle();
articleList.add(article);

在 article 元素中創建 author 元素。
java.util.List authorList=article.getAuthor();
authorList.add("Jason Hunter");

與使用上面說明的步驟創建的 journal 元素相似,添加另外一個 journal 元素,以創建示例 XML 文檔 OracleCatalog.xml。然後將 CatalogImpl 對象編組到一個 XML 文檔。
marshaller.marshal(catalog, new FileOutputStream(xmlDocument));

這就生成了 OracleCatalog.xml:
<?xml version="1.0" encoding = 'UTF-8'?>
<catalog title="Oracle Magazine" publisher="Oracle Publishing" xmlns="http://jaxbderived/catalog">
<journal date="November-December 2003">
<article section="XML">
<title>Updating XQuery</title>
<author>Jason Hunter</author>
</article>
</journal>

<journal date="September-October 2003">
<article section="SQL">
<title>The Active Database</title>
<author> Cameron ORourke</author>
</article>
</journal>
</catalog>

下面所示爲 XMLConstructor.java,它是用於從這些 Java 類創建 XML 文檔的程序:
import jaxbderived.catalog.*;
import oracle.xml.jaxb.*;
import oracle.xml.parser.v2.*;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.xml.bind.*;

public class XMLConstructor
{
public void generateXMLDocument(File xmlDocument){
try
{

JaxbContextImpl jaxbContext=new JaxbContextImpl();
Marshaller marshaller=jaxbContext.createMarshaller();


ObjectFactory factory=new ObjectFactory();
CatalogImpl catalog=(CatalogImpl)(factory.createCatalog());
catalog.setTitle("Oracle Magazine");
catalog.setPublisher("Oracle Publishing");


JournalImpl journal=(JournalImpl)(factory.createJournal());
journal.setDate("November-December 2003");



ArticleImpl article=(ArticleImpl)(factory.createArticle());

article.setSection("XML");
article.setTitle("Updating XQuery");



java.util.List journalList=catalog.getJournal();

journalList.add(journal);

java.util.List articleList=journal.getArticle();

articleList.add(article);

java.util.List authorList=article.getAuthor();
authorList.add("Jason Hunter");


journal=(JournalImpl)(factory.createJournal());
journal.setDate("September-October 2003");


article=(ArticleImpl)(factory.createArticle());

article.setSection("SQL");
article.setTitle("The Active Database");


journalList=catalog.getJournal();

journalList.add(journal);

articleList=journal.getArticle();

articleList.add(article);

authorList=article.getAuthor();
authorList.add("Cameron ORourke");

marshaller.marshal(catalog, new FileOutputStream(xmlDocument));

}catch (IOException e)
{
System.out.println(e.toString());

}
catch (JAXBException e)
{
System.out.println(e.toString());

}

}
public static void main (String[] argv)
{ String xmlDocument=argv[0];
XMLConstructor xmlConstructor=new XMLConstructor();
xmlConstructor.generateXMLDocument(new File(xmlDocument));
}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章