Sweet Brissie life

ブリスベンでのサトウキビ博士研究生活の甘くない備忘録

Rでxmlをいじる...XML & xml2パッケージ

またまたささやかな技術的な話。

 

研究で使ってる作物モデルのプログラム(APSIM)だけれど、そのGUIは残念ながらパラメータ推定とか大規模なシナリオ分析には向かないので、自分の場合は使い慣れているRでのスクリプト上にプログラムの実行やインプットの書き換えなどを組み込んで操作してる。

 

そのプログラムの実行のために読み込まれるのがxml形式のファイルで、それらに書き込まれたパラメータとかをR側からいじるためにやってみたことの備忘録。

 

パッケージはXMLとxml2。

install.packages("XML")
install.packages("xml2")

 

なんでもXMLはもうあまりメンテされてないのでxml2に移行した方が良いよ、みたいなのがあった。

Switching an R package from XML to xml2 · GitHub

けど今回の自分の調べた範囲では片方に統一できなかった....もしよりすっきりした使い方があればぜひご教授くださいませ。

 

xmlファイル読み込み

read_xml(xml_file_path)

 

xml表示

XML::xmlParse(xml)

さっそくXMLの方に頼ってるのだが、ファイル全体を眺めるならこの方がよさげ。

 

・特定のnodeを探す

xml_find_all(xml, "//node_name")

目的のnode_nameがいくつかの階層を経た先であっても、//で一気にたどり着けるし、更に//を繋げて明示的に階層を辿ってもよい。

 

・特定のnodeの値を書き換える

xml_set_text(node, "text_to_be_inserted") 

第一引数に目的のnode、第二引数に入れる値を指定する...お察しの通り、nodeは上記のxml_find_all()を入れ子にできるので、

xml_set_text(xml_find_all(xml, "//node_name")), "text_to_be_inserted") 

こんな感じの使い方になる。

 

・特定のnodeのattributeを書き換える

xml_set_attr(node, attr="attr_name", value="attr_value")

nodeは上記同様xml_find_all()を入れ子にできる。

attributeっていうのね、<node name="node A">text</node>てなってる時のname。

 

・特定のnodeを置き換える

xml_replace(node_old, node_new, copy=T)
 node_oldをnode_newで置き換える感じ。copy=Tにしないとnode_newは元の場所から削除される。

 

・子nodeを挿入する
xml_add_child(node_to_be_inserted, "chile_node_name", "node_value")

 

さて、随分と雑な備忘録だけど、実際に自分が使ったのはこんなもん。

 自分の場合元になるxmlは存在してて、そのtextとかattributeをちょこちょこいじって、nodeの塊が大きいときは別ファイルにしてreplaceって感じだから使った機能は少ないのかな。

Function reference • xml2

元も子もないけど、これ見たら上記以外のお求めのものも載ってるはず。

 

 

ちなみにxmlもtxtファイルのような扱いにして、pasteで文字列を一行まるまるよういして, replaceで行指定して入れ替え、 writeでファイルに書き込むなどのいじり方もできる。

でもやっぱりxmlとして階層構造を生かしたままいじった方がコードもすっきりしやすいように思われたので今回こっちのやり方に移行した次第。

 

 

調べてて興味が出てきたのは、ウェブ解析への応用。

これらのパッケージはxmlだけじゃなくhtmlファイルをいじるのにも使われる。確かに同じような階層構造だもんね。

Rとウェブ解析:便利!Rで読み込むxmlファイル

 

スクレイピングとか、そのうちやってみたいな。でもまだ特に必要になる目的無いな。

【R言語】rvestによるWebスクレイピングのやり方①

ノート: スクレイピング:HTML編