MarkLogic アプリ開発チュートリアル：XMLから読み込んだ内容をデータベースに書き込む

NoSQL製品であるMarkLogicのチュートリアル第２回です。

[単純なチュートリアル](http://qiita.com/makopo/items/0d024b827880111f8a8f)から一歩進んで、ローカルから読み込んだXMLをMarkLogicデータベースにアップロードするサンプルを作ってみます。今回は、固定のURLではなく、URLを都度生成することにします。

以下の手順を既に済ませている前提で説明します。

* [MarkLogicのユーザーの作成](http://qiita.com/makopo/items/0d024b827880111f8a8f#marklogicのユーザーの作成)
* [Javaプロジェクトの作成](http://qiita.com/makopo/items/0d024b827880111f8a8f#javaプロジェクトの作成)
* [Java APIライブラリのダウンロード](http://qiita.com/makopo/items/0d024b827880111f8a8f#marklogic-java-apiライブラリのダウンロード)

## 準備

XMLファイルを```test.xml```という名前で作成し、プロジェクトのルートフォルダに配置します。日本語対応を確認するために、あえてShift-JISで保存してみます。

```xml:test.xml
<?xml version="1.0" encoding="Shift-JIS"?>
<deadbeats>
    <row>
        <name>あああ</name>
        <creditrating>いいい</creditrating>
    </row>
</deadbeats>
```

UTF-8で作る場合は、1行目のShift-JISをUTF-8に変えてください。

## クラスの作成

```java:WriteXMLDataFromFile.java
    public static void main(String[] args) {

        // データベースクライアントの取得
        DatabaseClient client = DatabaseClientFactory.newClient(
                "localhost", 8000, "aaa", "pass", DatabaseClientFactory.Authentication.DIGEST
        );

        // DocumentManagerの取得
        XMLDocumentManager xmlMgr = client.newXMLDocumentManager();

        // URIテンプレートの作成
        DocumentUriTemplate uriTemplate = xmlMgr.newDocumentUriTemplate("xml");

        // 新規作成したファイルは、常に/my/docs/で始まる
        uriTemplate.setDirectory("/my/docs/");

        try {

            // 入力ストリームの取得
            InputSource source = new InputSource("test.xml");

            // Handleの取得
            InputSourceHandle handle = new InputSourceHandle(source);

            // 生成されたURLに内容を書き込む
            DocumentDescriptor documentDescriptor = xmlMgr.create(uriTemplate, handle);

            // 生成されたURIをコンソールに出力
            System.out.println("Created: " + documentDescriptor.getUri());

        } catch (Exception e) {
            // エラーが発生したら中断
            throw new RuntimeException(e);

        } finally {
            // データベースクライアントの解放
            client.release();
        }

    }
```

* ```TextDocumentManager```ではなく、```XMLDocumentManager```を使っています。
* ```StringHandle```ではなく、```InputSourceHandle ```を使っています。
* URIの自動生成のために、```DocumentUriTemplate```のオブジェクトを作っています。
* ```XMLDocumentManager```の```create()```に上述のオブジェクトを渡しています。```write()```ではありません。

### MarkLogicでの文字コードの扱い

MarkLogicは内部的にテキスト、XML、JSONをUTF-8で扱います。MarkLogicのJava APIの内部では、UTF-16(Java内部で処理される文字コード)からUTF-8への変換が行われます。XML宣言できちんと文字コードを書いていれば、```InputSourceHandle```、```XMLEventReaderHandle```、```XMLStreamReaderHandle```は、XML文書の内容をUTF-8に変換してデータベースに格納してくれます。

詳細は、公式ドキュメントの Conversion of Document Encoding を参照してください。
http://docs.marklogic.com/guide/java/document-operations#id_11208

## 実行

ビルドして実行します。

```shell-session
22:29:43.030 [main] DEBUG c.m.client.DatabaseClientFactory - Creating new database client for server at localhost:8000
22:29:43.051 [main] DEBUG c.m.client.impl.JerseyServices - Connecting to localhost at 8000 as aaa
22:29:43.349 [main] INFO  c.m.client.impl.DocumentManagerImpl - Creating content
22:29:43.350 [main] DEBUG c.m.client.impl.JerseyServices - Sending new document in transaction null
Created: /my/docs/3193325293466088864.xml
22:29:43.550 [main] INFO  c.m.client.impl.DatabaseClientImpl - Releasing connection
22:29:43.550 [main] DEBUG c.m.client.impl.JerseyServices - Releasing connection
```

何回か実行した後、クエリコンソールで確認します。```/my/docs/```の後に毎回違う名前でXMLが作成されています。

![list2.png](https://qiita-image-store.s3.amazonaws.com/0/10290/61c6e53d-8bc0-0420-2f00-fdee6c5fee6a.png)

リンクをクリックし、コンテンツを開くと、XML宣言はUTF-8で、先ほどアップロードしたドキュメントが文字化けなく表示されます。

![contents.png](https://qiita-image-store.s3.amazonaws.com/0/10290/c53e7a12-2a59-f152-09b6-62f79e42f151.png)