2

3つのXMLファイルのセットが与えられた場合:

first.xml

<root>
    <item1>A</item1>
    <complexItem>
        <item2>B</item2>
        <item3>C</item2>
    </complexItem>
</root>

patch1.xml

<root>
     <item1>X</item1>
</root>

patch2.xml

<root>
     <complexItem>
         <item3>Y</item>
     </complexItem>
     <differentItem>Z</differentItem>
<root>

最終的にXMLを作成したいと思います。

patched.xml

<root>
    <item1>X</item1>
    <complexItem>
        <item2>B</item2>
        <item3>Y</item2>
    </complexItem>
    <differentItem>Z</differentItem>
</root>

したがって、パッチの新しい要素は付加的であり、パッチの既存の要素は破壊的です。これらの追加と更新は、ドキュメントツリーの任意のレベルで実行できます。理想的には、これは引数としてファイルのリストを受け取ることができるMavenプラグインですが、Javaでのソリューション(つまり、利用可能なライブラリ-すでに行われているはずの何かを再発明することを避けようとしています!)は問題ありませんプラグインを自分で書くことができるので。各ファイル(ベースとパッチ)は常に同じルート要素を持ちます。


追加する必要があります。ツリーから要素を削除するユースケースはありません(ファイル置換の階層的な性質により、パッチが適用されたファイルを使用するアプリケーションのエラーケースになります)。構築済みのツールまたはライブラリをもう少し検索しましたが、適切なものが見つからなかったため、dom4jを使用してゼロから何かを構築するというAndrewのアドバイスを受けました。dom4jにはまったくなじみがありませんが、これが私が思いついたものです(レビュー/エラー処理/適切なコメントなどなしで):

public void execute(){

    // Environment specific file loading removed

    SAXReader reader = new SAXReader();
Document patchedDocument = null;
for (InputStream is : loadedFiles) {
    Document d = null;
    try {
        d = reader.read(is);
    } catch (DocumentException e) {
        e.printStackTrace();
    }
    if (patchedDocument == null) {
        patchedDocument = d;
    } else {
        Element root = d.getRootElement();
        patch(patchedDocument, root);
    }
}

    // Environment specific file writing

}

private void patch(Document patchedDocument, Element element) {

    for (Iterator i = element.elementIterator(); i.hasNext();) {
        Element nextElement = (Element) i.next();
        if (nextElement.isTextOnly()) {
            String path = nextElement.getUniquePath();
            Node n = patchedDocument.selectSingleNode(path);
            if (n != null)
            {
                                // This already exists and needs content replacing    
                n.setText(nextElement.getText());
            }else{
                                // This doesn't exist and needs to be added to the tree
                addElement(patchedDocument, nextElement);
            }
        } else {
            patch(patchedDocument, nextElement);
        }
    }
}

private Node addElement(Document patchedDocument, Element element)
{
    Element parent = element.getParent();
    String parentPath = parent.getPath();
    Node n = patchedDocument.selectSingleNode(parentPath);
    if (n == null){
        return addElement(patchedDocument, parent);
    } else {
        ((Branch)n).add(element.detach());
        return n;
    }
}
4

1 に答える 1

0

ファイルがメモリに収まるほど小さい場合は、Javaコードを記述して、すべてを個別のDOMにまとめ、説明した加法/破壊ロジックに基づいて1つのDOMにマージしてから、マージされたDOMを吐き出します。ターゲットファイルに出力します。XMLファイルの読み取りと書き込みに使用できるJavaライブラリがいくつかあります(例:dom4j)。XMLを自分で解析または構築しようとすることに煩わされたくはありません。

于 2013-01-17T11:09:44.170 に答える