Java : LSSerializer (XML) - API使用例

LSSerializer (Java SE 17 & JDK 17) の使用例まとめです。
だいたいのメソッドを網羅済みです。
API仕様のおともにどうぞ。


概要

LSSerializerは、DOM文書をXMLに直列化する(書き込む)ためのAPIを提供します。 XMLデータは文字列または出力ストリームに書き込まれます。

クラス構成

DOMを文字列に変換するには、よく Transformer が使われます。
ただし、Transformer は汎用的に設計されたAPIのため、DocumentType や EntityReference が思うように変換できないこともあるかもしれません。

一方、DOMLS の LSSerializer を使えば DocumentType や EntityReference をそのまま出力できます。

final var xml = """
        <!DOCTYPE root [
            <!ENTITY aaa "bbb">
        ]>
        <root>&aaa;</root>
        """;

final var factory = DocumentBuilderFactory.newInstance();
factory.setExpandEntityReferences(false);

final var builder = factory.newDocumentBuilder();
final var document = builder.parse(new ByteArrayInputStream(xml.getBytes()));

final var domImpl = builder.getDOMImplementation();

final var feature = domImpl.getFeature("LS", "3.0");
if (feature instanceof DOMImplementationLS ls) {
    final var serializer = ls.createLSSerializer();
    final var str = serializer.writeToString(document);
    System.out.println(str);

    // 結果
    // ↓
    //<?xml version="1.0" encoding="UTF-16"?><!DOCTYPE root [
    //<!ENTITY aaa 'bbb'>
    //]>
    //<root>&aaa;</root>
}

関連記事:XML (DOM) の基本


メソッド

DOMConfiguration getDomConfig ()

DOMノードの直列化中にLSSerializerが使用するDOMConfigurationオブジェクト。

final var factory = DocumentBuilderFactory.newInstance();
final var builder = factory.newDocumentBuilder();
final var domImpl = builder.getDOMImplementation();

final var feature = domImpl.getFeature("LS", "3.0");
if (feature instanceof DOMImplementationLS ls) {
    final var serializer = ls.createLSSerializer();
    final var domConfig = serializer.getDomConfig();

    final var names = domConfig.getParameterNames();
    for (int i = 0; i < names.getLength(); i++) {
        final var name = names.item(i);
        final var param = domConfig.getParameter(name);
        System.out.println(name + " : " + param);
    }

    // 結果
    // ↓
    //canonical-form : false
    //cdata-sections : true
    //check-character-normalization : false
    //comments : true
    //datatype-normalization : false
    //element-content-whitespace : true
    //entities : true
    //infoset : false
    //namespaces : true
    //namespace-declarations : true
    //split-cdata-sections : true
    //validate : false
    //validate-if-schema : false
    //well-formed : true
    //discard-default-content : true
    //format-pretty-print : false
    //ignore-unknown-character-denormalizations : true
    //xml-declaration : true
    //http://www.oracle.com/xml/jaxp/properties/isStandalone : false
    //jdk.xml.isStandalone : false
    //error-handler : null
}

LSSerializerFilter getFilter ()

アプリケーションでフィルタが用意されていると、直列化処理は各ノードを直列化する前にフィルタを呼び出します。

final var factory = DocumentBuilderFactory.newInstance();
final var builder = factory.newDocumentBuilder();
final var domImpl = builder.getDOMImplementation();

final var feature = domImpl.getFeature("LS", "3.0");
if (feature instanceof DOMImplementationLS ls) {

    final var xml = """
            <root>
              <child><aaa/><bbb/><ccc/></child>
            </root>
            """;

    final var input = ls.createLSInput();
    input.setStringData(xml);

    final var parser = ls.createLSParser(DOMImplementationLS.MODE_SYNCHRONOUS, null);
    final var document = parser.parse(input);

    final var serializer = ls.createLSSerializer();
    System.out.println(serializer.getFilter()); // null

    //<?xml version="1.0" encoding="UTF-16"?><root>
    //  <child><aaa/><bbb/><ccc/></child>
    //</root>
    System.out.println(serializer.writeToString(document));

    final var filter = new LSSerializerFilter() {
        @Override
        public short acceptNode(Node n) {
            System.out.println("acceptNode : " + n);

            if (n.getNodeName().equals("bbb")) {
                return NodeFilter.FILTER_REJECT;
            } else {
                return NodeFilter.FILTER_ACCEPT;
            }
        }

        @Override
        public int getWhatToShow() {
            return NodeFilter.SHOW_ELEMENT;
        }
    };

    serializer.setFilter(filter);
    System.out.println(filter == serializer.getFilter()); // true

    System.out.println("-- write start --");

    final var ret = serializer.writeToString(document);

    System.out.println("-- write end --");
    System.out.println(ret);

    // 結果
    // ↓
    //-- write start --
    //acceptNode : [root: null]
    //acceptNode : [child: null]
    //acceptNode : [aaa: null]
    //acceptNode : [aaa: null]
    //acceptNode : [bbb: null]
    //acceptNode : [bbb: null]
    //acceptNode : [ccc: null]
    //acceptNode : [ccc: null]
    //acceptNode : [child: null]
    //acceptNode : [root: null]
    //-- write end --
    //<?xml version="1.0" encoding="UTF-16"?><root>
    //  <child><aaa/><ccc/></child>
    //</root>
}

String getNewLine ()

書き出されているXMLで使用される行末シーケンス文字です。

final var factory = DocumentBuilderFactory.newInstance();
final var builder = factory.newDocumentBuilder();
final var domImpl = builder.getDOMImplementation();

final var feature = domImpl.getFeature("LS", "3.0");
if (feature instanceof DOMImplementationLS ls) {
    final var serializer = ls.createLSSerializer();

    final var ret1 = serializer.getNewLine();
    System.out.println(Arrays.toString(ret1.getBytes())); // [10]
    System.out.println(ret1.equals("\n")); // true

    serializer.setNewLine("\r\n");

    final var ret2 = serializer.getNewLine();
    System.out.println(Arrays.toString(ret2.getBytes())); // [13, 10]
    System.out.println(ret2.equals("\r\n")); // true
}

void setFilter (LSSerializerFilter filter)

アプリケーションでフィルタが用意されていると、直列化処理は各ノードを直列化する前にフィルタを呼び出します。

このメソッドの使用例は、getFilter() にまとめて記載しました。
そちらのAPI使用例をご参照ください。

void setNewLine (String newLine)

書き出されているXMLで使用される行末シーケンス文字です。

このメソッドの使用例は、getNewLine() にまとめて記載しました。
そちらのAPI使用例をご参照ください。

boolean write (Node nodeArg, LSOutput destination)

LSSerializerインタフェースの一般的な説明で、前述のように指定されたノードを直列化します。

final var factory = DocumentBuilderFactory.newInstance();
final var builder = factory.newDocumentBuilder();
final var domImpl = builder.getDOMImplementation();

final var feature = domImpl.getFeature("LS", "3.0");
if (feature instanceof DOMImplementationLS ls) {

    final var document = builder.newDocument();

    final var root = document.createElement("root");
    document.appendChild(root);

    final var text = document.createTextNode("abcd");
    root.appendChild(text);

    final var path = Path.of("R:", "java-work", "sample.xml");
    System.out.println(path); // R:\java-work\sample.xml

    try (final var writer = Files.newBufferedWriter(path)) {

        final var destination = ls.createLSOutput();
        destination.setCharacterStream(writer);

        final var serializer = ls.createLSSerializer();

        final var ret = serializer.write(document, destination);
        System.out.println(ret); // true
    }

    //<?xml version="1.0" encoding="UTF-8"?><root>abcd</root>
    System.out.println(Files.readString(path));
}

String writeToString (Node nodeArg)

LSSerializerインタフェースの一般的な説明で、前述のように指定されたノードを直列化します。

final var factory = DocumentBuilderFactory.newInstance();
final var builder = factory.newDocumentBuilder();
final var domImpl = builder.getDOMImplementation();

final var feature = domImpl.getFeature("LS", "3.0");
if (feature instanceof DOMImplementationLS ls) {

    final var document = builder.newDocument();

    final var root = document.createElement("root");
    document.appendChild(root);

    final var text = document.createTextNode("abcd");
    root.appendChild(text);

    final var serializer = ls.createLSSerializer();
    final var str = serializer.writeToString(document);

    //<?xml version="1.0" encoding="UTF-16"?><root>abcd</root>
    System.out.println(str);
}

boolean writeToURI (Node nodeArg, String uri)

エンコーディングを指定せず、LSOutput.systemIdをuri引数に設定して、LSOutputでLSSerializer.writeが呼び出されたかのように機能する簡易メソッドです。

final var factory = DocumentBuilderFactory.newInstance();
final var builder = factory.newDocumentBuilder();
final var domImpl = builder.getDOMImplementation();

final var feature = domImpl.getFeature("LS", "3.0");
if (feature instanceof DOMImplementationLS ls) {

    final var document = builder.newDocument();

    final var root = document.createElement("root");
    document.appendChild(root);

    final var text = document.createTextNode("abcd");
    root.appendChild(text);

    final var path = Path.of("R:", "java-work", "sample.xml");
    System.out.println(path); // R:\java-work\sample.xml

    final var uri = path.toUri();
    System.out.println(uri); // file:///R:/java-work/sample.xml

    final var serializer = ls.createLSSerializer();

    final var ret = serializer.writeToURI(document, uri.toString());
    System.out.println(ret); // true

    //<?xml version="1.0" encoding="UTF-8"?><root>abcd</root>
    System.out.println(Files.readString(path));

    // ------------------------
    // 注意:Windows では writeToURI で指定したファイルを削除しようとすると失敗します。
    // (すぐにリソース解放してくれていない?)
    // ファイルへ出力する場合は、writeToURI ではなく write メソッドを使った方が
    // よいかもしれません。
    try {
        Files.delete(path);
    } catch (IOException e) {
        System.out.println(e);
    }

    // 結果
    // ↓
    //java.nio.file.FileSystemException: R:\java-work\sample.xml:
    // プロセスはファイルにアクセスできません。別のプロセスが使用中です。
}

関連記事

ページの先頭へ