2016-06-16 11 views
0

StAXイテレータAPIを使用してSVGファイルの一部の属性の値を置き換えようとしています。 XMLEventReaderを使って元のファイルを読んで、要素をチェックして変更してから、XMLEventWriterに書き込んでいます。StAXを使用して小さな変更(属性の変更など)を行うXMLレイアウト(属性の順序、改行)を保持

<?xml version="1.0" encoding="UTF-8"?> 
<!-- 
... 
--> 
<!DOCTYPE ... 
... 
]> 
<svg ... 

私が手出力が同じではありません:

私の元のファイルは、以下の構造を有する

<?xml version="1.0"?><!-- 
... 
--><!DOCTYPE ... 
... 
]><svg ... 

あなたが見ることができるように、encodingは周りの改行だけでなく、なくなっていますコメントとdoctype。

また、結果ファイル内のすべてのタグのすべての属性の順序はランダムであるようです。 another questionを読みましたが、属性の順序は保証されていませんが、これは私には役立ちません。

これらのSVGファイルはGitにありますので、プレーンテキストのレイアウトは可能な限り保存していきたいと思います。

これらの問題を解決するにはどうすればよいですか?私の現在の仕事では、解析値を使わずに属性値をプレーンテキストとして置き換えることができましたが、タグのネストやそのようなことを考慮に入れるための解決策が必要です。

StAXで実行できない場合は、私は全く別のアプローチに対応しています。私はすでにDOMのアプローチを試みてきましたが、それはさらに悪化しています。おそらく、いくつかの3Dパーティパーサーがあります...

答えて

0

属性の更新、最良のオプションはXMLEventWriterを使用せず、代わりにXMLファイル内のタグの位置(文字オフセット)を検索し、部分文字列の置換を行います。あなたはこのようにそれを行うことができます:あなたは、属性を変更XMLEvent#getLocation()を使用して、位置を返します。これは、その上にgetCharacterOffset()を呼び出したい要素が発生したときにXMLEventReaderを使用して

  1. は、ファイル
  2. を反復処理しますこのイベントが発生した元のファイルに保存されます。
  3. 以前の要素と現在の要素のオフセットをトラッキングすることで、元のファイルの内容から1つの要素だけを含む部分文字列を抽出することができます。
  4. 部分文字列を更新し、その前後のテキストに結合します。これにより、更新されたXMLが文字列として取得されます。抽出された部分文字列には要素が1つしか含まれていないので、すべての属性が一意であるとみなしても差し支えありませんので、誤って他の要素に触れることは心配する必要はありません。
  5. 更新された内容を文字列としてファイルに書き込みます。

ダウンサイド:手動の属性を解析する必要がありますが、これはほとんどの場合簡単です。


また、私はCharactersイベントに問題が見つかりました:彼らは、その後の<または</がすでに消費された後に報告されています。たとえば、<foo>bar</foo>の場合、bar文字はbar</のように表示されます。

これは、StAXの他の実装では異なる場合があります。私はJavaライブラリのデフォルトのものを使用しています。この動作は、StAXパーサが後退しないという事実によって説明され、文字終了イベントを検出するのに十分な情報を持っている場合、すでに次の要素(開始または終了タグ)の先頭を消費していると仮定します。 XMLEventWriterを使用するには、私の元の試みについては


  • XMLヘッダーにencodingが欠落して明示的に新しいStartDocumentイベントを構築することで追加することができます。
  • 不足している改行を手動で追加することはできますが、それらを保存するフラグは見つかりませんでした。上の問題に関連しているようです。パーサーは、改行文字とともにこれらの要素のオフセットを報告します(時々追加されることがあります)。あなたの提案のための
1

VTD-XML(私が著者であるオープンソースプロジェクト)は、XMLツリーの階層構造をエクスポートしながら解析した後に基礎となるバイトを保存するJava APIです...これは、ドキュメントの無関係な部分の不要な操作を行わずに、その場でバイトの任意の部分を置き換えることができることを意味します。オーバーヘッドがゼロの直接的なオーバーヘッド...

+0

おかげで@ VTD-XML-著者で述べたように、属性の

  • ランダムな順序は、カスタム・パーサーで固定することができますが、私は、この特定のケースで動作する別の解決策を見つけました。 – scriptin

  • 関連する問題