Linux上で、
xmlstarletを使って、2つのxmlファイルを合成しようとしています。
一つ目のファイル、"list.xml"の内容は以下です。
---
<?xml version="1.0"?>
<x>
<e a="1">value1</e>
<e a="2">value2</e>
</x>
---
エレメントのリストです。
二つ目のファイル、"elem.xml"の内容は以下です。
---
<?xml version="1.0"?>
<x>
<e a="3">value3</e>
</x>
---
このファイルのエレメントを、list.xmlに付け加えようとしています。
最終的に、以下の内容のファイルを合成しようとしています。
---
<?xml version="1.0"?>
<x>
<e a="1">value1</e>
<e a="2">value2</e>
<e a="3">value3</e>
</x>
---
xmlstarletを使って、
$ xml ed -s "/x" -t elem -n e -v value3 -s "/x/e[last()]" -t attr -n a -v 3 list.xml
とすれば、目的の合成された内容が得られるんですが、あくまで、他のファイルからエレメントを
コピーしたいんです。
例えば、↓のコマンドは間違ってるんですが、イメージに一番近いものです。
$ xml ed -m "document('elem.xml')/x/e" "/x" list.xml
現状は、sedでlist.xmlの行末を削り、elem.xmlの内容をリダイレクトで追記し(>> list.xml)、
その後、削ったlist.xmlの行末を再び追記してますが、エレガントに解決できないでしょうか。
No.1ベストアンサー
- 回答日時:
WinXPで実験してみた
・・・・が,エレガントじゃ全然ない。
ファイル名が気に入らなかったというか考えながら打つのが面倒くさいので
list.xml → hoge.xml
elem.xml → fuga.xml
となっている。
Editだとどうしても厳密に指定しなきゃいけなさそうな気がするので
諦めて新たにXSLTモドキを書いて別ファイル作ってしまえ!という策に出ることにした。こんなコマンド書くなら素直にXSLTファイルを別に用意してXSLTプロセッサに流したほうが楽だろうなあとは思う。
C:\xmlstarlet-1.0.1>xml sel -t -m "/x" -e "x" -m "@*" -c "." -b -m "e" -c "." -b -c "document('./fuga.xml')/x/e" -b
./hoge.xml
出力結果は以下の通り。
<x><e a="1">value1</e><e a="2">value2</e><e a="3">value3</e></x>
●ルート要素が共に各ファイルは/x/eという構造をしているものとしてのみ想定し,/x/aとか/x/text()があることは考慮されてない。
なお,一応XSLTの規格によれば
http://www.w3.org/TR/xslt#section-Creating-Eleme …
xsl:elementのname属性はattribute value templateらしいので
「ルート要素の要素名」という指定も可能だ。解説はしないので自分で読んどくれ。
●hoge.xmlのルートのx要素に属性が存在していた場合には一応コピーするようにしたが,fuga.xmlのルートのx要素と属性が異なっていた場合は保証しない。
最後にこのコードをXSLTに直しておく。
面倒くさいのでxsl:output要素のencoding属性等コマンドラインでも
以下のシートでも指定してないのでUTF-16になる可能性大ですが。その辺はヘルプ見て。
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/x">
<xsl:call-template name="t1"/>
</xsl:template>
<xsl:template name="t1">
<xsl:element name="x">
<xsl:for-each select="@*">
<xsl:copy-of select="." />
</xsl:for-each>
<xsl:for-each select="e">
<xsl:copy-of select="." />
</xsl:for-each>
<xsl:copy-of select="document('./fuga.xml')/x/e" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
この回答への補足
その後、色々と試してみて以下のような方法も見付けました。
$ cat <<EOF |xml ed -m "//e" "/x" |xml ed -d "/x/x" >list-new.xml
> <x>
> $(xml fo -o list.xml)
> $(xml fo -o elem.xml)
> </x>
> EOF
xml fo で余分な部分をstrip、catのヒアドキュメントを使い合成した
xmlファイルを xml ed で成形する力技的解決方法です。
回答頂きありがとうございます。
特にXSLTコードの添付、どのような環境でも実行できる汎用性が高い方法
のように見受けられます。これを、とっかかりに調べてみます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- XML XML同じ名前の要素を自動で集約するツール 1 2022/04/11 09:21
- Visual Basic(VBA) vbaのエラー対応(実行時エラー7:メモリが不足しています) 4 2023/04/24 00:20
- Visual Basic(VBA) vbaの構文の修正相談(xmlファイルを順に開いてコピペ作業) 1 2023/04/22 01:18
- WordPress(ワードプレス) ワードプレスにて .xmlファイルの使い方をご存知の方、よろしくお願いいたします。 2 2022/09/30 00:55
- XML Windowsで見かけるxmlファイルってどういうものですか? 1 2022/06/03 14:57
- XML iPhoneでXMLファイルを開くにはどうしたら良いのでしょうか? 1 2022/09/05 18:00
- AJAX 自作の地図をグーグルマップのようにしたい 3 2022/11/15 11:53
- その他(IT・Webサービス) 見たことのない形式で日付が表示されているのでそれを解析してほしい 3 2023/01/23 16:53
- アプリ おすすめのパスワード管理アプリを教えてください。(iOSとWindows対応) 4 2023/01/19 02:08
- 数学 この数学問題、スマートに解く方法を教えてください。 3 2023/01/26 23:17
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
xmlファイルが上手にHTMLに変換...
-
xsltを利用して変換後改行が入る
-
XML、XSLTの適応エラー(IEから...
-
CPUの考え方を教えてください ...
-
XMLで要素が記述された順番に意...
-
バッチファイルでテキストファ...
-
昔Winnyってありましたけど、あ...
-
あせんうぶり言語
-
XSLで、XMLの空タグを制御したい。
-
VB6でXMLを作成しているのです...
-
SNMP リンクダウンとノードダ...
-
あるノードリストに、特定の名...
-
HTTPステータス 404 - There is...
-
コンテキストメニュークリック...
-
ノードの並び替え
-
Listからのnull要素を削除方法は?
-
ルート要素ノードが2個ある場合?
-
ノードとは
-
このエラー、何とかなりません...
-
html→xmlの変換
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
XML、XSLTの適応エラー(IEから...
-
xmlファイルが上手にHTMLに変換...
-
xalan でエラーが出るんですが。
-
XSLT
-
XSLTでの正規表現判定
-
不特定ノードに出現する同じタ...
-
XMLを勉強中なのですが・・・
-
XML+XSLTでの表示について
-
東芝のDynabookなのですがアン...
-
CPUの考え方を教えてください ...
-
昔Winnyってありましたけど、あ...
-
SNMP リンクダウンとノードダ...
-
ルート要素ノードが2個ある場合?
-
バッチファイルでテキストファ...
-
XMLで要素が記述された順番に意...
-
UTF-8でエンコーディングとはど...
-
あるノードリストに、特定の名...
-
google croud にあるファイルを...
-
XPathで途中に名前空間が設定さ...
-
同じタグ名の項目取得
おすすめ情報