Excel VBAで xmlデータを扱うときは名前空間に注意する
目次
サンプルデータと取得方法
サンプルデータと名前空間
下図をサンプルデータとして、データの取得方法を説明する。
3行目で名前空間が記述されている。また、6,7行目では名前空間が2つ記述されている。
① xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01"
② xmlns:ns2="http://mws.amazonservices.com/schema/Products/2011-10-01/default.xsd"
①は接頭辞(prefix)が記述されていない。②は「ns2」が記述されている。
このサンプルデータでは、どのダグが①に属し、②に属するのか?
答えは、すべて①の名前空間に属する。「ns2」の接頭辞が付いているタグが無いからだ。
XPathでデータ取得するための"おまじない"
まず、個別のデータ取得処理を記述する前に、おまじない的なコードを書く必要がある。
|
|
2行目でxmlオブジェクトを作成して、5行目でサンプルデータが記載されているxmlファイルを読み込んでいる。9行目で同期処理を指定。10行目はXPathを使うためのおまじない。
13~15行目で、プログラム内で使う名前空間の接頭辞を決めている。xmlファイルをロードした時点で名前空間もxmlオブジェクトに入っているのだが、接頭辞を仮にでも決めないとデータ取得できない。この接頭辞の名前は何でもよい。サンプルデータに記載されていた「ns2」に一致させる必要もない。但し、一致させておいた方が無用な混乱を避けられるだろう。
個別のデータ取得方法
◆ 次のコードを実行すると、サンプルデータ4行目の属性statusの値「Success」を取得することができる。
xml.SelectSingleNode("//a:GetLowestOfferListingsForASINResult").getAttribute("status")
SelectSingleNodeの引数にXPathを書いている。ルートから「GetLowestOfferListingsForASINResult」というノード(タグ)を探して、見つかったノードのstatus属性値をgetAttributeで取得している。 また、サンプルデータではこのノードに名前空間の接頭辞は付いていないが、プログラムでは必ず指定する必要がある。
◆ 次のコードを実行すると、サンプルデータの11行目の
xml.SelectSingleNode("//a:ASIN").text
◆ サンプルデータの15行目と44行目は同じタグだ。図1ではサンプルデータの末尾まで示していないが、実は繰り返しこのタグは出現している。このタグ内には商品状態を示す
|
|
3行目のSelectNodesで、
エラーケース
プログラム内で使う接頭辞を決めなかった場合
次のsample.xmlを読み込み、TitleとURLを出力する処理を検討してみる。
|
|
これを実行すると12行目でエラーとなり、図2のメッセージが表示される。
ロードしたsample.xmlに記載の接頭辞「a:」をXPath指定しているにも関わらず、エラーとなる。XPathで目的のタグを探すときは、必ずロード前に xmlns:a='https://dampgblog.hinohikari291.com/vbaxmlnamespace/' のように接頭辞付きで
名前空間を設定しておく必要がある。
6行目のコメントを外せば、正常に動作する。このコメントを外して実行すると、イミディエイトに以下のログが吐かれる。
名前空間の記述ミス
プログラム内で名前空間の接頭辞を書いてはいるものの、名前空間を示すURLが実際のxmlデータに記載の内容と異なっている場合は、図3のようなエラーとなる。例えば、以下のような 1234567890 などという出鱈目なコードを書いた場合である。
xml.SetProperty "SelectionNamespaces", "xmlns:a='1234567890'"
XPathで指定するタグに接頭辞を付けなかった場合
MSXML では接頭辞なしで名前空間を指定する方法がないようなので、適当な接頭辞を決めて XPath を書く必要がある。 図4のように、For Each 文の xml.SelectNodes("//LowestOfferListing")の部分で、接頭辞「a:」を付けていないため、Forループ内に進まないことが分かる。
参考サイト
Namespaces in XML 1.0 (Third Edition) W3C Recommendation 8 December 2009
https://www.w3.org/TR/xml-names/#iri-use
名前空間を理解しDOMの概要をつかむ
https://www.atmarkit.co.jp/fxml/rensai2/xmlmaster13/master13.html