XMLEXISTSでXPathを判定
最後の例では、SQL 2003の新しいXMLEXISTS述語でのXPathの使い方を示します。
Statement s = c.createStatement(); ResultSet rs = s.executeQuery("SELECT ID FROM ARTICLE WHERE " + "XMLEXISTS('//author[text()=\"John Smith\"]' PASSING BY REF " + "DATA)");
XMLQUERY関数を使用して任意のXQuery式を実行することもできます。しかし、XMLEXISTS述語とXMLQUERY関数は機能的にJDBC 4よりもSQL 2003寄りであるため、この記事ではこれ以上言及しません。
import java.io.StringReader; import java.sql.*; public class XmlDbTester { static final String XML1 = "<article>" +"<title>First Article</title>" +"<author>John Smith</author>" +"<body>A very short article.</body>" +"</article>"; static final String XML2 = "<article>" +"<title>Second Article</title>" +"<author>Mary Jones</author>" +"<body>Another short article.</body>" +"</article>"; static final String XML3 = "<article>" +"<title>Third Article</title>" +"<author>John Smith</author>" +"<body>Last short article.</body>" +"</article>"; static final String[] ARTICLES = {XML1, XML2, XML3}; public static void main(String s[]) { XmlDbTester xdt = new XmlDbTester(); Connection c = xdt.getConnection(); xdt.loadDemoData(c); xdt.demoXmlResult(c); xdt.demoXPath(c); xdt.closeConnection(c); System.out.println("Done"); System.exit(0); } void demoXmlResult(Connection c) { try { Statement s = c.createStatement(); ResultSet rs = s.executeQuery("SELECT XMLSERIALIZE (DATA AS CLOB) " + "FROM ARTICLE WHERE ID = 2"); while(rs.next()) System.out.println( "The article XML for article with ID = 2: \n" + rs.getString(1)); s.close(); rs.close(); } catch(Exception e) { e.printStackTrace(); } } void demoXPath(Connection c) { try { Statement s = c.createStatement(); ResultSet rs = s.executeQuery("SELECT ID FROM ARTICLE WHERE " + "XMLEXISTS('//author[text()=\"John Smith\"]' PASSING BY REF " + "DATA)"); while(rs.next()) System.out.println("John Smith wrote article with ID: " + rs.getInt(1)); s.close(); rs.close(); } catch(Exception e) { e.printStackTrace(); } } void loadDemoData(Connection c) { try { Statement s = c.createStatement(); s.execute("CREATE TABLE ARTICLE(ID INTEGER, DATA XML)"); System.out.println("Created demo table: ARTICLE"); s.close(); PreparedStatement ps = null; int id = 1; for(String insert : ARTICLES) { ps = c.prepareStatement( "INSERT INTO ARTICLE (ID, DATA) VALUES " + "(?, XMLPARSE (DOCUMENT CAST (? AS CLOB) PRESERVE " + "WHITESPACE))"); ps.setInt(1, id++); ps.setClob(2, new StringReader(insert)); ps.executeUpdate(); } System.out.println("Inserted test data into ARTICLE"); if(ps != null ) ps.close(); } catch(SQLException e) { e.printStackTrace(); } } Connection getConnection() { Connection c = null; try { c = DriverManager.getConnection( "jdbc:derby:XmlDemo;create=true"); c.setAutoCommit(false); } catch (Exception e) { e.printStackTrace(); } return c; } void closeConnection(Connection c) { try { c.close(); } catch(Exception e) {} } }
無限の可能性
SQL/XMLのサポートでコードの見通しがよくなり、開発期間が短縮されます。通常、XMLデータをデータベースに格納するのは、それなりの事情があるからです。記事、イベントリスト、製品情報など、さまざまなメディアをオンラインで表示する最も一般的な手法の1つは、データ全体をXMLとして格納し、変換を経てそのデータをオンラインで表示するというものでしょう。java.sql.SQLXML APIドキュメントには、新しいデータ型からの変換方法が多数掲載されていますが、次の例を見てみましょう。これもJava SE 6ドキュメントに掲載されているものです。
File xsltFile = new File("transformer.xslt"); File xhtmlFile = new File("xhtml.xml"); Transformer xslt = TransformerFactory.newInstance().newTransformer( new StreamSource(xsltFile)); Source source = sqlxml.getSource(null); Result result = new StreamResult(xhtmlFile); xslt.transform(source, result);
sqlxml変数は、データベースから取得したjava.sql.SQLXMLのインスタンスです。変換は必要ありません。データベースに格納されたXMLコンテンツを、わずか5行でXHTMLに変換できるというわけです。
