2

複数のXMLノードをソースXMLファイルからターゲットファイルにコピーしたいと思います。ソースファイルとターゲットファイルはどちらも非常に大きいため、StAXを使用します。通常、私が処理しようとしているファイルは次のようになります。

<root>
  <header>
    <title>A List of persons</title>
  </header>
  <person>
    <name>Joe</name>
    <surname>Bloggs</surname>
  </person>  
  <person>
    <name>John</name>
    <surname>Doe</surname>
  </person>  
  .
  .
  etc...
</root>

ターゲットファイルは次の形式である必要があります。

<root>
  <header>
    <title>A List of persons</title>
  </header>
  <person>
    <name>Joe</name>
    <surname>Bloggs</surname>
  </person>
</root>

ここで、各ファイルにはヘッダーノードが含まれている必要があります。正確に1人のノードがすべてルートノード内に含まれています。

ここでの問題は次のとおりです。XMLStreamReaderを介してソースファイルを読み込み、XMLStreamWriterを使用して書き込もうとしています。どちらも、ソースファイルからターゲットファイルにフラグメントをコピーするTransformerインスタンスに接続されています。トランスフォーマーは次のように作成されます。

TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

StAXSource stAXSource = new StAXSource(reader);
StAXResult stAXResult = new StAXResult(writer);

XML入力ストリーム内の目的のフラグメントにカーソルを移動するカスタムメイドのメソッドもあります。

// Moves XMLStreamReader cursor to the next fragment. 
moveCursorToNextFragment(XMLStreamReader reader, String fragmentNodeName)

そのため、最終的には次のようになります。

// Open file as usual...

// Advance cursor to <header> node, and copy fragment till
// </header> to the output writer. 
moveCursorToNextFragment(reader, "header");
transformer.transform(stAXSource, stAXResult);

// Advance cursor to <person> node, and copy fragment till
// </person> to the output writer.
moveCursorToNextFragment(reader, "person");
transformer.transform(stAXSource, stAXResult);

問題は、結果のXMLファイルに2つのXML宣言セクションが含まれていることです。

transformer.transform(stAXSource, stAXResult);

次のように、 StreamResultを使用して出力を変換しようとしました。

transformer.transform(stAXSource, new StreamResult(myStream));

XML宣言は省略されていますが、StAXResultの使用に戻ると、XML宣言が再び使用されます。また、OutputKeys.OMIT_XML_DECLARATIONは、オンかオフかに関係なく影響を与えないことに気付きました(値が「yes」のOutputKeys.STANDALONEなどの他の設定も同様です)。

つまり、宛先結果としてのStAXResultの場合、Transformerでグローバルに設定されたこれらの設定は無視されているようです。

私の質問はこれです:Transformer.transform()を呼び出すたびにTransformerがXML宣言を発行しないようにする(つまり、XML宣言なしでフラグメントを書き込む)ように、これを実現する方法はありますか?

あなたの助けは大いに感謝され、必要とされています。

4

2 に答える 2

2

XalanSAX2StAXStreamWriterはこれを行っています。別のXSLT実装は、動作が異なる場合があります。これを回避するには、ライターをラップして、startDocument(...)メソッドに何もしないように強制します。StAXONライブラリはStreamWriterDelegate、必要なコードを短くするのに役立つユーティリティクラスを提供します。

writer = new StreamWriterDelegate(writer) {
  @Override public void writeStartDocument() {}
  @Override public void writeStartDocument(String version) {}
  @Override public void writeStartDocument(String encoding, String version) {}
};

トリックを行う必要があります。

于 2012-03-30T09:38:41.970 に答える