Excel-VBAでXMLの複数ノードの取り出し

このQ&Aのポイント
  • Excel2007のVBAでXMLの扱いがわかっておらず、複数のItemノードからASINを取得するプログラムがうまくいかない。
  • MSXML2を使おうとしたらExcel2007では使えず、XMLDOMは古いため、MSXML2を使用する方法を知りたい。
  • XMLを取得するまでは成功しており、selectSingleNodeではうまく取得できるが、SelectNodesを使った場合に問題がある。
回答を見る
  • ベストアンサー

Excel-VBAでXMLの複数ノードの取り出し

すみません、いつも、いろいろな方に助けて頂いていますが、また、初歩的な質問をさせて頂きます。 Excel2007のVBAでXMLの扱いが良くわかっておりません。 以下のプログラムで複数ItemのASINを出力したいのですが、うまくいきません。 XMLがきちんと取得できているのはWireSharkでキャプチャして確認できております。 VBAで表示出力するのがうまくいきません。ご教授方よろしくお願いします。 selectSingleNodeで一つの場合はうまく取り出せています。複数ノードの場合にSelectNodesの使い方に問題がありますでしょうか? 型の宣言などに誤りがありますでしょうか? また、基本的なことですが、MSXML2を使おうとしたら、Excel2007で使えませんでした。 XMLDOMは、サポート切れ?で古いので、MSXML2を使うのが良いとWebで見ました。 DLLなどが必要な気がしているのですが、よくわかっていないのでご教授頂きたいです。 すみませんが、よろしくお願いします。 *****VBAプログラム(抜粋)****** Dim xml As Object, xmlItems As Object, objPrice As Object 'XML オブジェクト作成 Set xml = CreateObject("Microsoft.XMLDOM") xml.async = False xml.Load URI Set xmlItems = xml.SelectNodes("ItemLookupResponse/Items/Item") For Each objPrice In xmlItems ' ASIN If Not objPrice.SelectSingleNode("ASIN") Is Nothing Then curWS.Cells(rowIndex, ASINCol) = objPrice.SelectSingleNode("ASIN").text End If Next *****取得したXML(抜粋)****** <ItemSearchResponse > <Items> <Item> <ASIN>111</ASIN> </Item> <Item> <ASIN>222</ASIN> </Item> <Item> <ASIN>333</ASIN> </Item> </Items> </ItemSearchResponse>

質問者が選んだベストアンサー

  • ベストアンサー
  • mitarashi
  • ベストアンサー率59% (574/965)
回答No.1

とりあえず下記で111,222,333が取得できました。ご参考まで。 当方、Windows7Home64bit/xl2010です。 環境は異なりますが、MSXML3あたりでも動くコードだと思います。 コード中XPATHはItemLookupResponseなのに、テストデータの方はItemSearchResponseになっていますが大丈夫ですか? 'MSXML6に参照設定 Sub test() Dim XML As New MSXML2.DOMDocument60 Dim xmlItems As IXMLDOMNodeList Dim objPrice As IXMLDOMNode XML.async = False ' XML.validateOnParse = False ' XML.resolveExternals = False ' XML.preserveWhiteSpace = True XML.Load GetDesktopPath & "\test.xml" 'お示しのデータをコピペして保存 Set xmlItems = XML.SelectNodes("ItemSearchResponse/Items/Item") For Each objPrice In xmlItems ' ASIN If Not objPrice.SelectSingleNode("ASIN") Is Nothing Then Debug.Print objPrice.SelectSingleNode("ASIN").Text End If Next '直接ASINまで指定しても良いと思うが... ' Set xmlItems = XML.SelectNodes("ItemSearchResponse/Items/Item/ASIN") ' If xmlItems.Length > 0 Then ' For Each objPrice In xmlItems ' Debug.Print objPrice.Text ' Next ' End If Set XML = Nothing End Sub Private Function GetDesktopPath() As String Dim wScriptHost As Object, strInitDir As String Set wScriptHost = CreateObject("Wscript.Shell") GetDesktopPath = wScriptHost.SpecialFolders("Desktop") Set wScriptHost = Nothing End Function

yamakiyo2
質問者

お礼

プログラムまで記載頂きありがとうございました。SelectNodesの考え方はあっているようですね。 参考になりました。根本的に何かができていないようですので、頂いたプログラムで勉強します。

関連するQ&A

  • VB2005でXMLデータから複数ある要素の入れ子を取得する方法

    VB2005、XML の初心者です。 VB2005でXMLデータをMSXMLで解析していますが、下記のようなXMLの場合、Itemがうまく解析できません。 Module > Parent > Item という親子関係ですが、 全て数は可変です。(子がない場合もあります。) <Body> <Content> <Module> </Module> <Module> <Parent> <Item>A</Item> </Parent> </Module> <Module> <Parent> <Item>AA</Item> <Item>BB</Item> <Item>CC</Item> </Parent> </Module> <Module> </Module> </Content> </Body> ソースは下記です。 Dim LmsxmlDoc As MSXML2.DOMDocument LmsxmlDoc = New MSXML2.DOMDocument LmsxmlDoc.LoadXml(XMLData) Dim LModules As MSXML2.IXMLDOMNodeList '下記Moduleは取得できる LModules = LmsxmlDoc.SelectNodes("/Body/Content/Module") Dim LItems As MSXML2.IXMLDOMNodeList Dim LmsxmlModule As MSXML2.DOMDocument LmsxmlModule = New MSXML2.DOMDocument For Each LModule As MSXML2.IXMLDOMNode In LModules '下記(1)でも(2)でもItemが取得できない (1)LItems = LModule.selectNodes("/Module/Parent/Item") LmsxmlModule.LoadXml(LModule.Xml) (2)LItems = LmsxmlModule.selectNodes("/Module/Parent/Item") For Each LItem As MSXML2.IXMLDOMNode In LItems '処理 Next Next 上記ソースでは、(1)、(2)のどちらの方法でもなぜかItemが取得できません。 Itemを取得するにはどうすれば良いのでしょうか。 ヒントでも良いので、皆様の知恵をお借りできれば幸いです。 よろしくお願い致します。

  • Access VBAでXMLが読み込めない

    Access2013でXMLファイルを読み込むVBAを作成しています。 VBA実行時に「実行時エラー '-2147467259(80004005)': 未宣言の名前空間の接頭語を参照します :'a'」と表示されてしまい読み込むことができません。 色々調べた結果、下記のページが今回のエラーに関係ありそうということは分かったのですが、VBAのソースをどのように書き換えれば良いか分からず苦戦しております。 http://support.microsoft.com/kb/280457/ja 解決法をご存じ方がいらっしゃいましたらご教授いただければと思います。 よろしくお願いします。 --------------以下ソース-------------- XMLファイル <?xml version="1.0"?> <rss version="2.0"> <a:b>0</a:b> <title>test</title> </rss> VBA本文 Sub readXml() Dim XDoc As MSXML2.DOMDocument Dim node As MSXML2.IXMLDOMNode Set XDoc = New MSXML2.DOMDocument If XDoc.Load(CurrentProject.Path & "\" & "a.xml") = False Then MsgBox "読み込み失敗" Exit Sub End If Dim rs As New ADODB.Recordset rs.Open "test", CurrentProject.Connection, , adLockOptimistic rs.AddNew    For Each node In XDoc.selectNodes("rss/title") rs!title = node.Text rs.Update rs.Close End Sub

  • VB2005でXMLから複数ある要素の項目を取得する方法

    VB2005、XMLの初心者です。 下記XMLの「ヤマダタロウ」を抽出するのがうまくいきません。 <Module> <Body> <Item Code= A TableId=001> <Name>ヤマダタロウ</Name> </Item> <Item Code= B TableId=001> <Name>山田太郎</Name> </Item> </Body> </Module> 上記XMLがmsxmlDocとして引数で下記プロシージャに渡されるのですが、selectNodesではなぜか取得できません。 どこか間違っているでしょうか。 Private Sub prvParseXML(Byval msxmlDoc As MSXML2.DOMDocument) Dim NodeList As MSXML2.IXMLDOMNodeList NodeList = msxmlDoc.selectNodes("/Module/Body/Item[@Code='A'][@tableId='001']/Name") End Sub 何かヒントになるようなことでも良いので、皆様の知恵をお借りできれば幸いです。 よろしくお願い致します。

  • XMLのタグの有無をPHPで判定したい。

    example1.xml ----------------------- <item>  <color>red</color>  <omake>candy</omake> </item> ----------------------- example2.xml ----------------------- <item>  <color>black</color> </item> ----------------------- 上記はXMLファイルの2パターンを示したものです。 商品(item)によって、オマケ(omake)があったりなかったりします。 オマケがない時には、タグ自体存在しません。 なので、タグがない時に、そのデータをDOMで取得しようとすると、 エラーが吐かれます。 Notice: Trying to get property of non-object in~~~ 私がしたいことは、 タグがない場合には、値を取得しない。 という分岐をさせることです。 例えば、 $items = $doc->getElementsByTagName('color'); if(isset($items)){echo $items->item(0)->nodeValue;} こんな感じで考えたのですが、ダメでした。 タグが無くても、$itemsはNULLではないため、 if文の中に入ってしまい、 結局、$items->item(0)->nodeValue; を通過しようとして、 Notice: Trying to get property of non-object in~~~ が吐かれます。 ($itemsは、object(DOMNodeList)#3 (0) { }といった内容で、NULLではない。) また、 if(isset($items->item(0)->nodeValue)){  echo $items->item(0)->nodeValue; } のようにすると、 isset()のところで、やはり、 $items->item(0)->nodeValue を通過しようとして、 Notice: Trying to get property of non-object in~~~ が吐かれます。 こういった場合、どうしたら良いのでしょうか。 宜しくお願いします。 (PHP5の環境です。)

    • ベストアンサー
    • PHP
  • VB2005でXMLデータの要素があるかどうかの判定について

    VB2005、XMLの初心者です。 XMLデータをMSXMLでパーサーにかけてから全項目を抽出していますが、要素は必須のものもあれば、省略される場合もあります。 下記の方法では、省略されている場合エラーとなってしまうのですが、 指定したパスの要素があるかどうか判定することはできないのでしょうか。 省略される可能性のある場合は、selectsingleNodeではなく、何か別の方法で項目を取得しなければならないのでしょうか。 Private Sub prvParseXML(Byval msxmlDoc As MSXML2.DOMDocument) Dim Item As String Dim TableId As String Item = msxmlDoc.selectsingleNode("/Mml/content/Module/Class/Code").Text TableId = msxmlDoc.selectsingleNode("/Mml/content/Module/Class/@tableId").Text End Sub 項目を抽出する方法は上記しか分からなかったのですが、 何かヒントになることでも良いので皆様の知恵をお借りできれば幸いです。 よろしくお願い致します。

  • VBAのXML処理でメモリが足りない?

    Excel2003のVBAでMSXML2.DomDocumentを使ってXMLの処理をしています。http経由でXMLを取得し、パースして、Sheetに書き込んでいます。 XMLの行数が少ないうちは問題ないのですが、行数が1600件を超えたあたりで、LoadXML()メソッドで落ちます。 XMLを分割して、500行ずつや100行ずつLoadXMLさせても、合計処理数が1600行あたりで、必ずLoadXML()に失敗します。 メモリ不足かと思って、ループするごごとにSet Dom = Nothingのようにしてオブジェクトをクリアしていますが、効果がありません。 処理させたいXMLは最大で8000行になります。 なんとか解決策はないでしょうか? 以下、ソースの一部です。 Dim Dom As New MSXML2.DOMDocument Function get_xml_dom(query) Dim MSX As Object Set Dom = New MSXML2.DOMDocument Dim Url As String host_address = "hostname" host_path = "/keyword_report/get_keyword_data" Url = "http://" & host_address & host_path & query Set MSX = CreateObject("MSXML2.XMLHTTP") MSX.Open "GET", Url, False MSX.Send If Dom.LoadXML(MSX.responseText) Then '<- 1600件ぐらい処理させるとここで落ちる Debug.Print "Load XML is True" get_xml_dom = True Else get_xml_dom = False Debug.Print "Load XML is False" End If Set MSX = Nothing End Function このあと、DomからXPATHで要素を取り出して、シートに埋め込んでいます。

  • XMLのソート

    XMLのソート http://okwave.jp/qa/q6069815.html に間違いがあったので訂正して再質問します。 このようなXMLがあります <?xml version="1.0" encoding="UTF-8" ?> <ROOT>  <CONTENTS>   (略)  </CONTENTS>  <ITEMS>   <ITEM>    <TITLE>ABC</TITLE>    <NUMBER>10</NUMBER>   </ITEM>   <ITEM>    <TITLE>DEF</TITLE>    <NUMBER>0</NUMBER>   </ITEM>   <ITEM>    <TITLE>GHI</TITLE>    <NUMBER>100</NUMBER>   </ITEM>   <ITEM>    <TITLE>JKL</TITLE>    <NUMBER>50</NUMBER>   </ITEM>  </ITEMS> </ROOT> これを、/ITEMS/ITEM/NUMBER でソートして <?xml version="1.0" encoding="UTF-8" ?> <ROOT>  <CONTENTS>   (略)  </CONTENTS>  <ITEMS>   <ITEM>    <TITLE>DEF</TITLE>    <NUMBER>0</NUMBER>   </ITEM>   <ITEM>    <TITLE>ABC</TITLE>    <NUMBER>10</NUMBER>   </ITEM>   <ITEM>    <TITLE>JKL</TITLE>    <NUMBER>50</NUMBER>   </ITEM>   <ITEM>    <TITLE>GHI</TITLE>    <NUMBER>100</NUMBER>   </ITEM>  </ITEMS> </ROOT> というようにしたいです。 XSLなどでできるのでしょうか? Excel2003のVBAでMSXMLを使っています。

    • ベストアンサー
    • XML
  • Access VBAで指定した要素を読み込みたい

    お世話になっております。 Access VBAでRSSを読み込み指定した要素の値を取得したいのですが、ググってもよく分からず どのようにすれば良いのか分からないので教えてください。 下記XMLの「item」の値を取得しフィールドへ値を挿入したいのです。 item_title1を読み込んだ後に次に別のレコードとしてitem_title2を読みたいといった形です。 初心者で言葉足らずの部分があると思いますが、ご教授の程よろしくお願いします。 VBA本文 Sub readXml() Dim XDoc As MSXML2.DOMDocument Dim node As MSXML2.IXMLDOMNode Set XDoc = New MSXML2.DOMDocument If XDoc.Load(CurrentProject.Path & "\" & "a.xml") = False Then MsgBox "読み込み失敗" Exit Sub End If Dim rs As New ADODB.Recordset 'データベースにデータを挿入する。 rs.Open "test", CurrentProject.Connection, , adLockOptimistic rs.AddNew    For Each node In XDoc.selectNodes("rss/content/title") rs!title = node.Text rs.Update rs.Close End Sub 取込元XML(RSS)ソース <?xml version="1.0"?> <rss version="2.0"> <content> <title>test/title> <language>ja</language> <item> <title>item_title1</title> </item> <item> <title>item_title2</title> </item> </content> </rss>

  • XMLへDOMでタグの追加

    次のようなXMLにDOMで、タグを追加しようとしているのですが、 追加される場所が思った所に追加されません。 正常XMLにようにしたいのですが、どうすれば良いでしょうか? --元XML----------------- <root> <item>a</item> <item>b</item> </root> --結果XML----------------- <root> <item>a</item> <item>b</item> <info>xxxx</info> </root> --正常XML----------------- <root> <info>xxxx</info> <item>a</item> <item>b</item> </root> -- プログラム ---------------- MSXML::IXMLDOMDocumentPtr xmlDoc = NULL; MSXML::IXMLDOMNodeListPtr pNodes; MSXML::IXMLDOMNodePtr pNode; MSXML::IXMLDOMElementPtr pElem; xmlDoc.CreateInstance ("Msxml2.DOMDocument"); xmlDoc->load( ファイル名 ); pNodes = xmlDoc->selectNodes(L"/root"); pNode = pNodes->Getitem(0); pElem = xmlDoc->createElement(L"info"); pNode->appendChild( pElem ); 環境:WinXP+IE7+VC6

    • ベストアンサー
    • XML
  • XMLの名前空間について

       どなたか教えてください。 例 xml <a xmlns="test"> <b attribute="test"> <c attribute="test2"> </c> </b> </a> というxmlをMSXML4.0を参照設定している   エクセルVBAでロードし、   Dim testdom as DOMDocument Dim testNode as As IXMLDOMNode  testdom.loadXML(test.xml) set testNode = testdom.selectsinglenode("/a/b")  ノードを取得し testNode.xml を取得すると、取得したxml内に、 先頭に宣言した、xmlns="test"が自動で付加された状態 で取得されるのですが、それはいたしかたない物なのでしょうか? 名前空間の宣言なしで取得することは可能なのでしょうか? どなたか教えてください。宜しくお願いします。

専門家に質問してみよう