13 Java DOM API for XMLType
Java DOM API for XMLType
では、DOMを使用してXMLType
インスタンスを操作できます。これを使用すると、Java Database Connectivity (JDBC)を介してXMLデータをフェッチするなど、JavaでXMLデータを操作できます。
- Java DOM API for XMLTypeの概要
Oracle XML DBはJava Document Object Model (DOM) Application Program Interface (API) forXMLType
をサポートします。これはXML Schemaに基づく文書とスキーマに基づかない文書の両方に対する、クライアントおよびサーバー用の汎用APIです。 - JDBCを使用したXMLTypeデータへのアクセス
Java Database Connectivity (JDBC)は、Oracle XML DB内のXML文書など、Oracle Database内のすべてのデータにアクセスするための、Javaアプリケーション用のSQLベースの方法です。 - JDBCを使用したXMLデータベース文書の操作
Oracle XML DBでJava Database Connectivity (JDBC)を使用して、データベースに格納されたXMLType
データを更新、挿入および削除できます。 - JDBCを使用した、データベースへの大規模なXML文書のロード
Java Database Connectivity (JDBC)を使用して大規模なXML文書をデータベースにロードするには、JavaCLOB
オブジェクトを使用して文書を保持し、JavaメソッドinsertXML()
を使用して挿入します。 - Thick接続を使用したJava DOM APIに対するMS Windows Javaセキュリティ・マネージャの権限
アプリケーションのセキュリティ・ポリシーを実装するためにMS Windows上でJavaセキュリティ・マネージャ(クラスSecurityManager
)を使用する場合は、Thick接続でJava DOM API forXMLType
を使用するために、特定の権限をセキュリティ・ポリシー・ファイルに追加する必要があります。 - XML Schemaに基づく文書の作成
XML Schemaに基づく文書を作成するには、Java DOM API forXMLType
の拡張機能を使用して、使用するXML Schema URLを指定します。また、作成中のDOMが指定されたXML Schemaに準拠するかどうか(適切な子が適切な文書に挿入されているか)も検証します。 - Java (JDBCまたはSQLJ)でのXMLTypeインスタンス表現
XMLType
インスタンスは、oracle.xdb.XMLType
によってJavaで表現されます。XMLType
インスタンスがJDBCまたはSQLJのクライアントを使用してフェッチされると、このインスタンスは提供されたXMLType
クラスのオブジェクトとして自動的に明示されます。 - Java DOM API for XMLTypeのクラス
Oracle XML DBは、W3CのDOMレベル2勧告をサポートします。また、アプリケーションとOracle XML Developer's Kit for Javaの相互作用を容易にするOracle固有の拡張機能も提供します。Java DOM API forXMLType
では、W3C DOMインタフェースを実装するクラスが提供されます。 - Java DOM API for XMLTypeの使用
XMLType
表または列からデータを取得し、そこからJavaXMLDocument
インスタンスを取得します。Java DOM API forXMLType
を使用して、データのDOMツリーの要素を操作します。 - Javaを使用した大規模XMLノードの処理
Oracle XML DBでは、抽象ストリームおよびストリーム操作の各メソッドが提供され、これらを使用して、64 KBを超えるXMLノードを処理できます。Thickまたはkprb接続でJavaクラスXMLNode
およびXMLAttr
を使用して、大規模ノードを操作します。 - バイナリXMLでのJava DOM APIおよびJDBCの使用
Java DOM API for XMLおよびJava Database Connectivity (JDBC)を使用して、Oracle XML DBに対して、バイナリXMLとしてエンコードされたXMLデータを読書きできます。この処理には通常の読書きプロシージャが関与します。
親トピック: XMLType API
13.1 Java DOM API for XMLTypeの概要
Oracle XML DBはJava Document Object Model (DOM) Application Program Interface (API) for XMLType
をサポートします。これはXML Schemaに基づく文書とスキーマに基づかない文書の両方に対する、クライアントおよびサーバー用の汎用APIです。
DOMは、XML文書のメモリー内ツリーベースのオブジェクト表現で、要素および属性へのプログラム・アクセスを可能にします。DOMオブジェクトおよびインタフェースは、W3C勧告の一部です。PL/SQL API for XMLTypeで説明したとおり、Oracle XML DB DOM APIは、W3CのDOMレベル1.0およびレベル2.0のコア勧告に準拠しています。
Java DOM API for XMLType
では、Oracle XML DBに格納されたすべての整形式のXML文書を処理します。XML文書は、XML Schemaに基づくかどうか、および基礎となるXMLType
記憶域モデルの形式に関係なく、同様に表示されます。Java DOM APIは、クライアントおよびサーバーの両方で動作します。
Java DOM API for XMLType
を使用すると、別のキャラクタ・セットでエンコードされたデータからXMLType
インスタンスを作成できます。
Java DOM API for XMLType
を使用して、JavaアプリケーションからOracle XML DBリポジトリに格納されたXML文書にアクセスできます。ネーミングは、W3CのDOM勧告で指定されている、DOMへのJavaバインディングに準拠しています。リポジトリには、XML Schemaに基づくドキュメントおよび基づかないドキュメントの両方を含めることができます。
JDBCを使用してXMLType
データにアクセスするには、クラスoracle.xdb.XMLType
を使用します。
Java DOM API for XMLType
は、Javaパッケージoracle.xml.parser.v2
を使用して実装されます。
13.2 JDBCを使用したXMLTypeデータへのアクセス
Java Database Connectivity (JDBC)は、Oracle XML DB内のXML文書など、Oracle Database内のすべてのデータにアクセスするための、Javaアプリケーション用のSQLベースの方法です。
Javaクラスoracle.xdb.XMLType
またはJavaインタフェースjava.sql.SQLXML
を使用して、XMLデータを作成します。
XMLデータのJDBC 4.0標準データ型はjava.sql.SQLXML
です。getObject()
メソッドでは、oracle.xdb.XMLType
型のオブジェクトが戻されます。Oracle Database 11gリリース2 (11.2.0.3)から、oracle.xdb.XMLType
がインタフェースjava.sql.SQLXML
を実装しています。
- JDBCを使用したOracle XML DB内のXML文書へのアクセス
JDBCユーザーは、XMLType
表を問い合せて、SQLXMLType
データ型でサポートされるすべてのSQL/XML関数をサポートするJDBCXMLType
インタフェースを取得できます。Java(JDBC)API forXMLType
インタフェースは、DOMDocumentインタフェースを実装できます。
親トピック: Java DOM API for XMLType
13.2.1 JDBCを使用したOracle XML DB内のXML文書へのアクセス
JDBCユーザーは、XMLType
表を問い合せて、SQL XMLType
データ型でサポートされるすべてのSQL/XML関数をサポートするJDBC XMLType
インタフェースを取得できます。Java(JDBC)API for XMLType
インタフェースは、DOMDocumentインタフェースを実装できます。
例13-1に、JDBCを使用してXMLType
表を問い合せる方法を示します。
次のいずれかの方法で、JDBCを使用してXMLType
データを選択できます。
-
SQLでSQL/XML関数
XMLSerialize
を使用し、Javaでoracle.jdbc.OracleClob
またはjava.lang.String
インスタンスとして結果を取得します。例13-2のJavaスニペットに、これを示します。 -
ResultSet
でメソッドgetSQLXML()
をコールして、SQLXML
インスタンス全体を取得します。このメソッドの戻り値は、java.sql.SQLXML
型です。次に、インタフェースSQLXML
でJavaメソッドを使用し、データにアクセスできます。この方法を例13-3に示します。
例13-3では、getObject()
メソッドを使用してResultSet
からXMLType
インスタンスを直接取得します。
例13-4では、XMLType
型の出力パラメータをSQL文にバインドします。この出力パラメータは、XMLType
データ型として登録されます。
例13-1 JDBCを使用したXMLType表の問合せ
PreparedStatement statement = connection.prepareStatement("SELECT e.poDoc FROM po_xml_tab e");
ResultSet resultSet = statement.executeQuery();
while(resultSet.next())
{
// Get result as SQLXML data.
// Use that to get a DomSource instance.
SQLXML sqlXml = resultSet.getSQLXML(1);
DomSource source = sqlXml.getSource(DOMSource.class);
// Get document from the DomSource instance as a DOM node.
Document document = (Document) source.getNode();
// Use the document object
...
}
例13-2 getString()およびgetCLOB()を使用したXMLTypeデータの選択
PreparedStatement statement = connection.prepareStatement(
"SELECT XMLSerialize(DOCUMENT e.poDoc AS CLOB) poDoc, " +
"XMLSerialize(DOCUMENT e.poDoc AS VARCHAR2(2000)) poString " +
" FROM po_xml_tab e");
ResultSet resultSet = statement.executeQuery();
while(resultSet.next())
{
// The first result is an OracleClob instance
OracleClob clob = resultSet.getClob(1));
// The second result is a String instance
String poString = resultSet.getString(2);
// Use clob and poString
...
}
例13-3 getSQLXML()を使用してXMLTypeデータを戻す方法
PreparedStatement statement = connection.prepareStatement(
"SELECT e.poDoc FROM po_xml_tab e");
ResultSet resultSet = statement.executeQuery();
while(resultSet.next())
{
// Get the SQLXML
SQLXML sqlXml = resultSet.getSQLXML(1);
// Convert the SQLXML to an xmlString instance
String xmlString = sqlXml.getString();
//Use the xmlString instance
...
}
例13-4 出力パラメータを使用してXMLTypeデータを戻す方法
public void doCall (String[] args) throws Exception
{
// CREATE OR REPLACE FUNCTION getPurchaseOrder(reference VARCHAR2)
// RETURN XMLTYPE
// AS
// xml XMLTYPE;
// BEGIN
// SELECT OBJECT_VALUE INTO xml
// FROM purchaseorder
// WHERE XMLCast(XMLQuery('$p/PurchaseOrder/Reference'
// PASSING OBJECT_VALUE AS "p" RETURNING CONTENT)
// AS VARCHAR2(30))
// = reference;
// RETURN xml;
// END;
String SQLTEXT = "{? = call getPurchaseOrder('BLAKE-2002100912333601PDT')}";
super.doSomething(args);
createConnection();
try
{
System.out.println("SQL := " + SQLTEXT);
CallableStatement sqlStatement = getConnection().prepareCall(SQLTEXT);
sqlStatement.registerOutParameter (1, java.sql.Types.SQLXML);
sqlStatement.execute();
SQLXML sqlXml = sqlStatement.getSQLXML(1);
System.out.println(sqlXml.getString());
}
catch (SQLException exception)
{
if (sqlStatement != null)
{
sqlStatement.close();
throw exception;
}
}
}
親トピック: JDBCを使用したXMLTypeデータへのアクセス
13.3 JDBCを使用したXMLデータベース文書の操作
Oracle XML DBでJava Database Connectivity (JDBC)を使用して、データベースに格納されたXMLType
データを更新、挿入および削除できます。
注意:
XMLType
メソッドtransform()
は、OCIドライバでのみ機能します。
Thin JDBCドライバでは、すべてのoracle.xdb.XMLType関数がサポートされているわけではありません。
oracle.xdb.XMLType
クラスとOCIドライバを使用しない場合、XMLのインテリジェント処理に関連したパフォーマンスのメリットを失う可能性があります。
XMLType
データを次のいずれかの方法で、更新、挿入または削除できます。
-
文字列を
INSERT
、UPDATE
またはDELETE
文にバインドし、SQL内でXMLType
コンストラクタを使用してXMLインスタンスを作成します。例13-5に、これを示します。 -
PreparedStatement
インスタンスでsetSQLXML()
を使用して、XMLType
インスタンス全体を設定します。例13-6に、これを示します。
SQLXML
値を選択すると、JDBCによって、列がSQLXML
として記述されます。列型の名前を選択し、それをSQLXML
と比較すると、SQLXML
インスタンスを処理しているかどうかを確認できます。例13-7に、これを示します。
例13-8では、XMLType
列に格納されているPurchaseOrder
要素内のdiscount
要素を更新します。ここでは、JDBCおよびSQLXML
を使用します。XMLパーサーを使用してDOMツリーを更新し、更新されたXML値をXMLType
列に書き込みます。
例13-5 SQLコンストラクタXMLTypeおよびJava文字列を使用したXMLType列の更新
PreparedStatement statement =
connection.prepareStatement("UPDATE po_xml_tab SET poDoc = XMLType(?)");
String poString = "<PO><PONO>200</PONO><PNAME>PO_2</PNAME></PO>";
// Bind the string
statement.setString(1,poString);
statement.execute();
例13-6 SQLXMLを使用したXMLType列の更新
PreparedStatement statement =
connection.prepareStatement("UPDATE po_xml_tab SET poDoc = ?");
String xmlString = "<PO><PONO>200</PONO><PNAME>PO_2</PNAME></PO>";
SQLXML sqlXml = connection.createSQLXML();
sqlXml.setString(xmlString);
// Bind the SQLXML
statement.setSQLXML(1, sqlXml);
statement.execute();
例13-7 JDBCを使用したXMLType列に関するメタデータの取得
PreparedStatement statement =
connection.prepareStatement("SELECT poDoc FROM po_xml_tab");
ResultSet resultSet = statement.executeQuery();
// Get the resultSet metadata
ResultSetMetaData mdata = (ResultSetMetaData)resultSet.getMetaData();
// The column type is SQLXML
if (mdata.getColumnType(1) == java.sql.Types.SQLXML)
{
// It is a SQLXML instance
}
例13-8 JDBCを使用したXMLType列の更新
public class UpdateXMLType
{
static String qryStr =
"SELECT x.poDoc from po_xml_tab x " +
"WHERE XMLCast(XMLQuery('/PO/PONO/text()'" +
" PASSING x.poDoc RETURNING CONTENT)" +
" AS NUMBER)" +
" = 200";
static String updateXML(String xmlTypeStr)
{
System.out.println("\n===============================");
System.out.println(xmlTypeStr);
System.out.println("===============================");
String outXML = null;
try
{
DOMParser parser = new DOMParser();
parser.setValidationMode(false);
parser.setPreserveWhitespace (true);
parser.parse(new StringReader(xmlTypeStr));
System.out.println("XML string is well-formed");
XMLDocument document = parser.getDocument();
NodeList nl = document.getElementsByTagName("DISCOUNT");
for(int i=0;i<nl.getLength();i++) {
XMLElement discount = (XMLElement)nl.item(i);
XMLNode textNode = (XMLNode)discount.getFirstChild();
textNode.setNodeValue("10");
}
StringWriter sw = new StringWriter();
document.print(new PrintWriter(sw));
outXML = sw.toString();
//Print modified xml
System.out.println("\n===============================");
System.out.println("Updated PurchaseOrder:");
System.out.println(outXML);
System.out.println("===============================");
}
catch (Exception e)
{
e.printStackTrace(System.out);
}
return outXML;
}
public static void main(String args[]) throws Exception
{
try
{
PreparedStatement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(qryStr);
while(orset.next())
{
//retrieve PurchaseOrder xml document from database
SQLXML sqlXml = resultSet.getSQLXML(1);
//store this PurchaseOrder in po_xml_hist table
statement = connection.prepareStatement("INSERT INTO po_xml_hist VALUES(?)");
statement.setSQLXML(1,sqlXml); // bind the SQLXML instance
statement.execute();
//update "DISCOUNT" element
String newXML = updateXML(sqlXml.getString());
// create a new instance of an XMLtype from the updated value
SQLXML sqlXml2 = connection.createSQLXML();
sqlXml2.setString(newXml);
// update PurchaseOrder xml document in database
statement = connection.prepareStatement(
"UPDATE po_xml_tab x SET x.poDoc =? WHERE " +
"XMLCast(XMLQuery('/PO/PONO/text()'" +
" PASSING value(xmltab) RETURNING CONTENT)" +
" AS NUMBER)" +
"= 200");
statement.setSQLXML(1, sqlXml2); // bind the XMLType instance
statement.execute();
connection.commit();
System.out.println("PurchaseOrder 200 Updated!");
}
//delete PurchaseOrder 1001
statement.execute("DELETE FROM po_xml x WHERE" +
"XMLCast(XMLQuery('/PurchaseOrder/PONO/text()'" +
" PASSING value(xmltab) RETURNING CONTENT)" +
" AS NUMBER)" +
"= 1001");
System.out.println("PurchaseOrder 1001 deleted!");
}
catch(Exception e)
{
e.printStackTrace(System.out);
}
}
}
例13-9 更新済の発注書
<?xml version = "1.0"?>
<PurchaseOrder>
<PONO>200</PONO>
<CUSTOMER>
<CUSTNO>2</CUSTNO>
<CUSTNAME>John Nike</CUSTNAME>
<ADDRESS>
<STREET>323 College Drive</STREET>
<CITY>Edison</CITY>
<STATE>NJ</STATE>
<ZIP>08820</ZIP>
</ADDRESS>
<PHONELIST>
<VARCHAR2>609-555-1212</VARCHAR2>
<VARCHAR2>201-555-1212</VARCHAR2>
</PHONELIST>
</CUSTOMER>
<ORDERDATE>20-APR-97</ORDERDATE>
<SHIPDATE>20-MAY-97 12.00.00.000000 AM</SHIPDATE>
<LINEITEMS>
<LINEITEM_TYP LineItemNo="1">
<ITEM StockNo="1004">
<PRICE>6750</PRICE>
<TAXRATE>2</TAXRATE>
</ITEM>
<QUANTITY>1</QUANTITY>
<DISCOUNT>10</DISCOUNT>
</LINEITEM_TYP>
<LINEITEM_TYP LineItemNo="2">
<ITEM StockNo="1011">
<PRICE>4500.23</PRICE>
<TAXRATE>2</TAXRATE>
</ITEM>
<QUANTITY>2</QUANTITY>
<DISCOUNT>10</DISCOUNT>
</LINEITEM_TYP>
</LINEITEMS>
<SHIPTOADDR>
<STREET>55 Madison Ave</STREET>
<CITY>Madison</CITY>
<STATE>WI</STATE>
<ZIP>53715</ZIP>
</SHIPTOADDR>
</PurchaseOrder>
親トピック: Java DOM API for XMLType
13.4 JDBCを使用した、データベースへの大規模なXML文書のロード
Java Database Connectivity (JDBC)を使用して大規模なXML文書をデータベースにロードするには、Java CLOB
オブジェクトを使用して文書を保持し、JavaメソッドinsertXML()
を使用して挿入します。
大規模なXML文書(通常4000文字を超える場合)がJDBCのString
オブジェクトを使用してXMLType
の表または列に挿入されると、次のランタイム・エラーが発生します。
"java.sql.SQLException: Data size bigger than max size for this type"
このエラーは、JavaのOracleClob
オブジェクトを使用して大規模なXML文書を保持することで回避できます。例13-10に、このテクニックを使用するコードを示します。これはXMLType
メソッドのinsertXML()
を定義します。これを使用して、大規模なXML文書が表poTable
のXMLType
の列purchaseOrder
に挿入されます。XMLType
表の場合も同じ方法を使用できます。
メソッドinsertXML()
では、XML文書を含むOracleClob
オブジェクトを使用します。インタフェースOracleClob
は、標準JDBCインタフェースjava.sql.Clob
のサブインタフェースです。メソッドinsertXML()
はOracleClob
オブジェクトをJDBCのプリコンパイルされた文にバインドします。これによりデータがXMLType
列に挿入されます。
insertXML()
を使用するための前提条件は、次のとおりです。
-
Oracle Databaseがリリース9.2.0.1以上であること。
-
ターゲット・データベース表が存在すること。例を実行する前に、次のSQLを実行してください。
CREATE TABLE poTable (purchaseOrder XMLType);
XMLType
メソッドのinsertXML()
の仮パラメータは、次のとおりです。
-
xmlString
-XMLType
列に挿入するXMLデータ -
connection
- データベース接続オブジェクト(Oracle Connection Object)
JavaメソッドinsertXML()
は、メソッドgetCLOB()
をコールして、XMLデータを格納するCLOB
オブジェクトを作成して戻します。getCLOB()
メソッドの仮パラメータは例13-11で定義され、次のとおりです。
-
xmlString
-XMLType
列に挿入するXMLデータ -
connection
- データベース接続オブジェクト(Oracle Connection Object)
例13-10 JDBCを使用したXMLType列の挿入
private void insertXML(Connection connection, String xmlString) { OracleClob clob = null; try { String query = "INSERT INTO potable (purchaseOrder) VALUES (XMLType(?)) "; // Get the statement Object PreparedStatement statement = connection.prepareStatement(query); // Get the OracleClob instance from xmlString clob = getOracleClob(connection, xmlString); statement.setObject(1, clob); // Execute the prepared statement if (statement.executeUpdate () == 1) { System.out.println ("Successfully inserted a Purchase Order"); } } catch(Exception exp) { exp.printStackTrace(); } finally { if(clob !=null) clob.close(); } }
例13-11 OracleClobインスタンスへのXML文字列の変換
private OracleClob getOracleClob(Connection connection, String xmlString) throws SQLException
{
OracleClob clob =(OracleClob) connection.createClob();
clob.setString(1, xmlString);
return clob;
}
親トピック: Java DOM API for XMLType
13.5 Thick接続を使用したJava DOM APIに対するMS Windows Javaセキュリティ・マネージャの権限
アプリケーションのセキュリティ・ポリシーを実装するためにMS Windows上でJavaセキュリティ・マネージャ(クラスSecurityManager
)を使用する場合は、Thick接続でJava DOM API for XMLType
を使用するために、特定の権限をセキュリティ・ポリシー・ファイルに追加する必要があります。
例13-12では、このようなポリシー・ファイルの内容を示しています。ここで、c:\myworkspace
はOracle XML DBに関連するjarを含むワークスペース・フォルダです。(ポリシー・ファイルは、同じフォルダにある必要があります。)
例13-12で使用しているライブラリは、orageneric12
およびoraxml12
です。最後の2文字(ここでは12
)は、データベースのメジャー・リリース番号に対応している必要があります(したがって、たとえばOracle Database 13 リリース2の場合、orageneric
13
とoraxml
13
を使用します)。
ポリシー・ファイルを作成すると、次のコマンドライン・スイッチを使用してプログラムを呼び出すことができます。
-Djava.security.manager=default -Djava.security.policy=c:\myworkspace\ojdbc.policy
例13-12 Java DOM APIの権限を付与するポリシー・ファイル
grant codeBase "file:c:\myworkspace
" {
permission java.lang.RuntimePermission "loadLibrary.orageneric12";
permission java.lang.RuntimePermission "loadLibrary.oraxml12";
}
grant codeBase "file:c:\myworkspace\xdb6.jar" {
permission java.lang.RuntimePermission "loadLibrary.orageneric12";
permission java.lang.RuntimePermission "loadLibrary.oraxml12";
}
grant codeBase "file:c:\myworkspace\ojdbc6.jar" {
permission java.lang.RuntimePermission "loadLibrary.orageneric12";
permission java.lang.RuntimePermission "loadLibrary.oraxml12";
}
親トピック: Java DOM API for XMLType
13.6 XML Schemaに基づく文書の作成
XML Schemaに基づく文書を作成するには、Java DOM API for XMLType
の拡張機能を使用して、使用するXML Schema URLを指定します。また、作成中のDOMが指定されたXML Schemaに準拠するかどうか(適切な子が適切な文書に挿入されているか)も検証します。
注意:
Java DOM API for XMLType
は型および制約のチェックは実行しません。
DOMオブジェクトの作成後は、Oracle XML DB Resource API for Javaを使用して、DOMオブジェクトをOracle XML DBリポジトリに保存できます。XML文書は次の適切な形式で格納されます。
-
BLOBインスタンス(スキーマに基づかない文書の場合)
-
XML Schemaで指定された形式(XML Schemaに基づく文書の場合)
例13-13では、Java DOM API for XMLType
を使用してDOMオブジェクトを作成し、関連するXML Schemaで指定された形式で格納します。この例では、XML Schemaに対する検証は示されていません。
例13-13 Java DOM APIを使用したDOMオブジェクトの作成
PreparedStatement statement = connection.prepareStatement(
"update po_xml_XMLTypetab set poDoc = ? ");
String xmlString = "<PO><PONO>200</PONO><PNAME>PO_2</PNAME></PO>";
OracleClob clob = (OracleClob)connection.createClob();
clob.setString(1, xmlString);
SQLXML sqlXml = clob.toSQLXML();
DOMSource domSource = sqlXml.getSource(DOMSource.class);
Document document = (Document) domSource.getNode();
Element rootElem = document.createElement("PO");
document.insertBefore(document, rootElem, null);
SQLXML sqlXml2 = clob.toSQLXML();
DOMResult domResult = sqlXml2.setResult(DomResult.class);
domResult.setNode(document);
statement.setSQLXML(1, sqlXml2);
statement.execute();
親トピック: Java DOM API for XMLType
13.7 Java (JDBCまたはSQLJ)でのXMLTypeインスタンス表現
XMLType
インスタンスは、oracle.xdb.XMLType
によってJavaで表現されます。XMLType
インスタンスがJDBCまたはSQLJのクライアントを使用してフェッチされると、このインスタンスは提供されたXMLType
クラスのオブジェクトとして自動的に明示されます。
このクラスのオブジェクトは、データ操作言語(DML)文の値としてバウンドできます。通常、この値はXMLType
です。
親トピック: Java DOM API for XMLType
13.8 Java DOM API for XMLTypeのクラス
Oracle XML DBは、W3CのDOMレベル2勧告をサポートします。また、アプリケーションとOracle XML Developer's Kit for Javaの相互作用を容易にするOracle固有の拡張機能も提供します。Java DOM API for XMLType
では、W3C DOMインタフェースを実装するクラスが提供されます。
XMLDocument
は、インスタンス化されたXML文書用にDOMを表すクラスです。次のようにして、文書および接続オブジェクトからSQLXML
インスタンスを取得できます。
SQLXML sqlXml = connection.createSQLXML();
DOMResult domResult = sqlXml.setResult(DOMResult.class);
domResult.setNode(document);
表13-1に、Java DOM API for XMLType
のクラスおよび実装されるW3CのDOMインタフェースを示します。Java DOM APIクラスは、oracle.xml.parser.v2
パッケージに入っています。
表13-1 Java DOM API for XMLType: クラス
Java DOM API for XMLTypeのクラス | W3CのDOMインタフェース勧告のクラス |
---|---|
XMLDocument |
org.w3c.dom.Document |
XMLCDATA |
org.w3c.dom.CDataSection |
XMLComment |
org.w3c.dom.Comment |
XMLPI |
org.w3c.dom.ProcessingInstruction |
XMLText |
org.w3c.dom.Text |
XMLEntity |
org.w3c.dom.Entity |
DTD |
org.w3c.dom.DocumentType |
XMLNotation |
org.w3c.dom.Notation |
XMLAttr |
org.w3c.dom.Attribute |
XMLDomImplementation |
org.w3c.dom.DOMImplementation |
XMLElement |
org.w3c.dom.Element |
XMLAttrList |
org.w3c.dom.NamedNodeMap |
XMLNode |
org.w3c.dom.Node |
関連項目:
OTNのOracle XML DB: アプリケーションとOracle XML Developer's Kit for Javaの相互作用のためのOracle拡張機能
親トピック: Java DOM API for XMLType
13.9 Java DOM API for XMLTypeの使用
XMLType
表または列からデータを取得し、そこからJava XMLDocument
インスタンスを取得します。Java DOM API for XMLType
を使用して、データのDOMツリーの要素を操作します。
Java DOM API for XMLType
を使用すると、任意のレベルにある文書内のノードを検索および取得できます。これにより、その場で(動的に)作成するなど、XML文書をプログラムで作成できます。これらの文書は、登録されたXML Schemaに準拠することもあれば、しないこともあります。Java API for XMLType
はDOM 2.0勧告に準拠し、名前空間を認識します。
図13-1に、Java DOM API for XMLType
の使用方法を示します脚注1。次のステップを実行します。
-
XMLType
表または表のXMLType
列からXMLデータを取り出します。XMLデータをフェッチすると、OracleによってDocument
インスタンスが作成されます。これにより、getNode()
メソッドを使用してXMLDocument
インスタンスを取得できます。 -
Java DOM API for
XMLType
を使用してDOMツリーの要素を操作します。変更されたデータはXMLType
インスタンスに格納されますが、データはJDBC更新を使用して戻されます。
XMLType
およびXMLDocument
インスタンスは、各クラスでfree()
メソッドを使用してクローズする必要があります。クローズすると、保持されていた基礎となるメモリーがすべて解放されます。
親トピック: Java DOM API for XMLType
13.10 Javaを使用した大規模XMLノードの処理
Oracle XML DBでは、抽象ストリームおよびストリーム操作の各メソッドが提供され、これらを使用して、64 KBを超えるXMLノードを処理できます。Thickまたはkprb接続でJavaクラスXMLNode
およびXMLAttr
を使用して、大規模ノードを操作します。
注意:
大規模ノード機能は、Thickまたはkprb接続でのみ動作します。Thin接続では動作しません。
Oracle Database 11gリリース(11.1)以前は、Oracle XML DBにより処理されるテキスト・ノードまたは属性値のサイズはそれぞれ64KBに制限されていました。リリース11.1以降、この制限はなくなりました。
以前ノードのサイズが制限されていたのは、ノード値を設定および取得するJavaメソッドでjava.lang.String
型の引数のみがサポートされていたためです。文字列の最大サイズはJava VMの実装により依存していますが、限定されています。リリース11.1以前は、oracle.xdb.dom.XDBNode.java
クラス内に含まれているノード値を管理するJava DOM APIは次のようになっていました。
public String getNodeValue (); public void setNodeValue (String value);
リリース11.1以前は、oracle.xdb.dom.XDBAttribute.java
クラス内に含まれている属性を管理するJava DOM APIは次のようになっていました。
public String getValue (); public void setValue (String value);
Oracle Database 11gリリース1 (11.1)から、パッケージoracle.xdb.dom
は非推奨になっています。このパッケージ内のJavaクラスXDBNode
およびXDBAttribute
は、パッケージoracle.xml.parser.v2
内でそれぞれクラスXMLNode
およびXMLAttr
に置き換えられています。また、これらのDOM APIはリリース11.1では拡張され、任意のサイズのテキスト・ノード値およびバイナリ・ノード値をサポートしています。
- Java DOMへのストリーム拡張
JavaString
、Reader
、およびWriter
データはすべてUCS2で表現されます。これは、データベース・キャラクタ・セットと同じではない場合があります。また、ノード文字データはキャラクタ・セットIDでタグ付けされており、ノード値が移入するときに設定されます。
関連トピック
親トピック: Java DOM API for XMLType
13.10.1 Java DOMへのストリーム拡張
Java String
、Reader
、およびWriter
データはすべてUCS2で表現されます。これは、データベース・キャラクタ・セットと同じではない場合があります。また、ノード文字データはキャラクタ・セットIDでタグ付けされており、ノード値が移入するときに設定されます。
次に示すoracle.xml.parser.v2.XMLNode.java
のメソッドにより、サイズが64KBを超えるノードにアクセスできます。リーフ・ノード(属性、PI
、CDATA
など)ではないノードを取得または設定しようとすると、これらのAPIにより例外が発生します。また、その値を実際に書き込み、ノードへのストリーム・アクセス状態を維持する場合に使用するリソースを解放するclose()
を使用してください。
- Get-Pullモデル
メソッドgetNodeValueAsBinaryStream()
およびgetNodeValueAsCharacterStream()
を使用して、取出しモードのパーサーによってDOMノードの値を取得できます。Oracle XML DBでは、パーサーによって書き込まれた入力ストリームからイベント・データを読み取ります。 - Get-Pushモデル
このモデルでは、プッシュ・モードのパーサーを使用して、DOMノードの値を取得します。Oracle XML DBでは、パーサーによって読み取られた出力ストリームにノード・データを書き込みます。 - Set-Pullモデル
このモデルでは、取出しモードのパーサーを使用して、DOMノードの値を設定します。Oracle XML DBでは、パーサーによって書き込まれた入力ストリームからイベント・データを読み取ります。 - Set-Pushモデル
このモデルでは、プッシュ・モードのパーサーを使用して、DOMノードの値を設定します。Oracle XML DBでは、パーサーによって読み取られた出力ストリームにノード・データを書き込みます。
親トピック: Javaを使用した大規模XMLノードの処理
13.10.1.1 Get-Pullモデル
メソッドgetNodeValueAsBinaryStream()
およびgetNodeValueAsCharacterStream()
を使用して、取出しモードのパーサーによってDOMノードの値を取得できます。Oracle XML DBでは、パーサーによって書き込まれた入力ストリームからイベント・データを読み取ります。
バイナリ入力ストリームの場合:
public java.io.InputStream getNodeValueAsBinaryStream ()
throws java.io.IOException,
DOMException;
メソッドgetNodeValueAsBinaryStream()
は、このクラスの定義メソッドを使用して読み取ることができる java.io.InputStream
のインスタンスを戻します。ノードのデータ型はRAW
またはBLOB
である必要があります。それ以外の場合は、IOException
が発生します。次の例では、バイナリ50バイトのセグメントのノード値を読み取っています。
...
oracle.xml.parser.v2.XMLNode node = null;
...
java.io.InputStream value = node.getNodeValueAsBinaryStream ();
// now read InputStream...
byte buffer [] = new byte [50];
int returnValue = 0;
while ((returnValue = value.read (buffer)) != -1)
{
// process next 50 bytes of node
}
...
文字入力ストリームの場合:
public java.io.Reader getNodeValueAsCharacterStream()
throws java.io.IOException,
DOMException;
メソッドgetNodeValueAsCharacterStream()
は、このクラスの定義メソッドを使用して読み取ることができるjava.io.Reader
のインスタンスを戻します。ノードのデータ型が文字でもCLOB
でもない場合、まずノード・データは文字に変換されます。すべてのノード・データは最終的には文字形式になり、必要に応じてUCS2
に変換されます。次の例では、50文字のセグメントのノード値を読み取っています。
...
oracle.xml.parser.v2.XMLNode node = null;
...
java.io.Reader value = node.getNodeValueAsCharacterStream ();
// now read InputStream
char buffer [] = new char [50];
int returnValue = 0;
while ((returnValue = value.read (buffer)) != -1)
{
// process next 50 characters of node
}
...
親トピック: Java DOMへのストリーム拡張
13.10.1.2 Get-Pushモデル
このモデルでは、プッシュ・モードのパーサーを使用して、DOMノードの値を取得します。Oracle XML DBでは、パーサーによって読み取られた出力ストリームにノード・データを書き込みます。
バイナリ出力ストリームの場合:
public void getNodeValueAsBinaryStream (java.io.OutputStream pushValue)
throws java.io.IOException,
DOMException;
pushValue
で指定されるjava.io.OutputStream
の状態はopenである必要があります。ノードのデータ型はRAW
またはBLOB
である必要があります。それ以外の場合は、IOException
が発生します。ノード・バイナリ・データはOutputStream
のwrite()
メソッドを使用してpushValue
に書き込まれ、ノード値が完全にストリームに書き込まれるとclose()
メソッドがコールされます。
文字出力ストリームの場合:
public void getNodeValueAsCharacterStream (java.io.Writer pushValue)
throws java.io.IOException,
DOMException;
pushValue
で指定されるjava.io.Writer
の状態はopenである必要があります。ノードのデータ型が文字でもCLOB
でもない場合、まずデータは文字に変換されます。常に文字形式のノード・データは必要に応じてUCS2
に変換され、java.io.Writer
にプッシュされます。
親トピック: Java DOMへのストリーム拡張
13.10.1.3 Set-Pullモデル
このモデルでは、取出しモードのパーサーを使用して、DOMノードの値を設定します。Oracle XML DBでは、パーサーによって書き込まれた入力ストリームからイベント・データを読み取ります。
バイナリ入力ストリームの場合:
public void setNodeValueAsBinaryStream (java.io.InputStream pullValue)
throws java.io.IOException,
DOMException;
pullValue
で指定されるjava.io.InputStream
の状態はopenである必要があります。ノードのデータ型はRAW
またはBLOB
である必要があります。それ以外の場合は、IOException
が発生します。pullValue
のバイナリ・データ全体がInputStream
のread()
メソッドを使用して読み取られ、ノード値を置換します。
import java.io.InputStream;
import oracle.xml.parser.*;
...
oracle.xml.parser.v2.XMLNode node = null;
...
byte [] buffer = new byte [500];
java.io.InputStream istream; //user-defined input stream
node.setNodeValueAsBinaryStream (istream);
文字入力ストリームの場合:
public void setNodeValueAsCharacterStream (java.io.Reader pullValue)
throws java.io.IOException,
DOMException;
pullValue
で指定されるjava.io.Reader
の状態はopenである必要があります。ノードのデータ型が文字でもCLOB
でもない場合、文字データはUCS2
からノード・データ型に変換されます。ノードのデータ型が文字またはCLOB
の場合、pullValue
から読み取られた文字データは、UCS2
からノードのキャラクタ・セットに変換されます。
親トピック: Java DOMへのストリーム拡張
13.10.1.4 Set-Pushモデル
このモデルでは、プッシュ・モードのパーサーを使用して、DOMノードの値を設定します。Oracle XML DBでは、パーサーによって読み取られた出力ストリームにノード・データを書き込みます。
バイナリ出力ストリームの場合:
public java.io.OutputStream setNodeValueAsBinaryStream ()
throws java.io.IOException,
DOMException;
メソッドsetNodeValueAsBinaryStream()
は、コール元によるノード値の書込み先となるjava.io.OutputStream
のインスタンスを戻します。ノードのデータ型はRAW
またはBLOB
である必要があります。それ以外の場合は、IOException
が発生します。次の例では、Oracle XML DBまたはOracle XML Developer's Kitが提供するjava.io.OutputStream
の実装に書き込むことで、ノード値をバイナリ・データに設定しています。
文字出力ストリームの場合:
public java.io.Writer setNodeValueAsCharacterStream ()
throws java.io.IOException,
DOMException;
メソッドsetNodeValueAsCharacterStream()
は、コール元によるノード値の書込み先となるjava.io.Writer
のインスタンスを戻します。書き込まれた文字データはまず、必要に応じてUCS2
からノードのキャラクタ・セットに変換されます。ノードのデータ型が文字でもCLOB
でもない場合、文字データはノード・データ型に変換されます。同様に、次の例では、Oracle XML DBまたはOracle XML Developer's Kitが提供するjava.io.Writer
の実装に書き込むことで、ノード値を文字データに設定しています。
import java.io.Writer;
import oracle.xml.parser.*;
...
oracle.xml.parser.v2.XMLNode node = null;
...
char [] buffer = new char [500];
java.io.Writer writer = node.setNodeValueAsCharacterStream ();
for (int k = 0; k < 10; k++)
{
byte segment [] = new byte [50];
// copy next subset of buffer into segment
writer.write (segment);
}
writer.flush ();
writer.close();
Oracle XML DBはwriter
またはOutputStream
を作成し、それをノード値が完全に書き込まれるまで繰り返しwrite()
メソッドをコールするユーザーに渡します。新規ノード値は、ユーザーがclose()
メソッドをコールするときのみ反映されます。
関連項目:
-
大規模ノードのためのC関数の詳細は、Oracle Database XML C APIリファレンスを参照してください。
親トピック: Java DOMへのストリーム拡張
13.11 バイナリXMLでのJava DOM APIおよびJDBCの使用
Java DOM API for XMLおよびJava Database Connectivity (JDBC)を使用して、Oracle XML DBに対して、バイナリXMLとしてエンコードされたXMLデータを読書きできます。この処理には通常の読書きプロシージャが関与します。
XMLデータは、データ型XMLType
を使用してOracle XML DBに格納でき、この抽象データ型の記憶域モデルの1つが、XMLデータの簡潔なXML Schema対応のエンコーディングであるバイナリXMLです。バイナリXMLはデータベース内のXMLType
の記憶域モデルとして使用することができますが、データベース外にあるXMLデータに対しても使用することができます。XMLデータのクライアント側処理には、Oracle XML DB内に格納されているデータや、データベース外に存在する一時データが関わることがあります。
バイナリXMLはXML Schemaに対応しており、必要性とデータに応じて、各種のコード体系を使用することができます。このため、バイナリXMLデータを操作するためには、関連するXML Schemaとエンコーディングについて、データとこのメタデータの両方が必要です。
データベースに格納されているXMLType
データの場合、このメタデータもデータベースに格納されます。ただし、データベースとデータのセットアップに応じて、メタデータが適用されるデータと同一のサーバーにメタデータが格納されない場合があります。この場合、データベースに対してバイナリXMLデータを読書きするためには、次のステップを実行する必要があります。
-
メタデータのコンテキスト・インスタンスを作成します。
-
このコンテキストを、データベース内のバイナリXMLデータにアクセスするために使用するデータ接続に関連付けます。データ接続は、専用接続でも接続プールでもかまいません。クラス
java.sql.Connection
のメソッドgetDedicatedConn()
およびgetConnPool()
を使用して、それらの接続の型に応じて、これら2つの接続型へのハンドルを取得します。
すると、アプリケーションがデータ接続上でバイナリXMLデータをエンコードまたはデコードする必要がある場合、それに必要なメタデータが自動的にフェッチされます。一連の動作の全体は次のとおりです。
-
クラス
java.sql.Connection
にXMLデータ接続オブジェクトを作成します。 -
パッケージ
oracle.xml.binxml
内のメソッドBinXMLMetadataProviderFactory.createDBMetadataProvider()
を使用して、必要に応じて1つ以上のメタデータ・コンテキストを作成します。メタデータ・コンテキストは、メタデータ・リポジトリと呼ばれることもあります。メタデータ・コンテキストは、専用接続または接続プールから作成することができます。 -
メタデータ・コンテキストをバイナリXMLデータ接続に関連付けます。これには、パッケージ
oracle.xml.binxml
内のメソッドDBBinXMLMetadataProvider.associateDataConnection()
を使用します。 -
(オプション) XMLデータがデータベース外に由来するものの場合は、メソッド
oracle.xdb.XMLType.setFormatPref()
を使用して、データベースに送信されるXMLデータがバイナリXML形式でエンコードされるように指定します。これは、DOM文書(クラスoracle.xdb.XMLType
)に適用されます。バイナリXMLを指定しない場合、データはテキストとしてデータベースに送信されます。 -
通常のJavaメソッドを使用して、データベースに対してXMLデータを読書きします。バイナリXML文書のエンコードやデコードに必要なときは常に、メタデータ・コンテキストを使用して、必要なメタデータが自動的にフェッチされます。
Java DOM API for XMLを使用して、クライアント・レベルのXMLデータに対して操作します。
例13-14に、これを示します。
例13-14 バイナリXML列でのJava DOM APIの使用
class PrintBinaryXML { public static void printBinXML() throws SQLException, BinXMLException { // Create datasource to connect to local database OracleDataSource ods = new OracleDataSource(); ods.setURL("jdbc:oracle:kprb"); System.out.println("Starting Binary XML Java Example"); // Create data connection Connection connection = ods.getConnection(); // Create binary XML metadata context, using connection pool DBBinXMLMetadataProvider repos = BinXMLMetadataProviderFactory.createDBMetadataProvider(); repos.setConnectionPool(ods); // Associate metadata context with data connection repos.associateDataConnection(connection); // Query XML data stored in SQLXML column as binary XML Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("SELECT doc FROM po_binxmltab"); // Get the SQLXML object while (resultSet.next()) { SQLXML sqlXml = resultSet.getSQLXML(1); // Convert SQLXML to a String String xmlString = sqlXml.getString(); System.out.println(xmlString); } resultSet.close(); statement.close(); connection.close(); System.out.println("Completed Binary XML Java Example"); } }
関連トピック
親トピック: Java DOM API for XMLType
脚注の説明
脚注1:ここでは、XMLデータがXML Schemaに登録済であり、XMLType
の列に格納されていると想定しています。