今だけ人気マンガ100円レンタル特集♪

こんにちは

あるXML文書を処理するために、VBAを使ってエクセルに書き出すスクリプトを書いています。
例えば、次のようなXMLファイルがあります。

<?xml version="1.0" encoding="utf-8"?>
<Recordset>
<RecordGroup>
<Record Id="1">
<RecRule xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://myschemas.org/Record.set">
<Description>1番目</Description>
<IgnoreCase>true</IgnoreCase>
</RecRule>
</Record>
<Record Id="2">
<RecRule xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://myschemas.org/Record.set">
<Description>アイディー2</Description>
<IgnoreCase>true</IgnoreCase>
</RecRule>
</Record>
</RecordGroup>
</Recordset>
--ここまで--
VBAで、MSXML2.DOMDocument60を使って読み込み、エクセル上に書き入れているのですが上記のRecRuleの部分に名前空間の定義があり、これが原因でその下のDescriptionを直接指定することができません。例えば、次のようなXPathではNothingが返されます。

Set Record = XML.SelectSingleNode("//Recordset/RecordGroup/Record[@Id='2']/RecRule/Description")

RecRuleに名前空間の定義がない場合や、名前空間ではない普通の属性値の設定であれば上記のXPathで要素が取得できることは確認できています。代替策として、Record[@Id='2']までを取得して、そのChildNodes(0)の~という具合で取得していくことはできるですが、もやもやっとするので解決したいと思っています。

このXML文書のフォーマットを私がかえることはできません。

Excel VBA, Windows 7 64bit

このQ&Aに関連する最新のQ&A

A 回答 (1件)

要素 RecRule とその子孫要素は接頭辞こそ省略されていますが、


れっきとした XML 名前空間が定義されています。

以下の二行は XML 的に同じ意味です。
<RecRule xmlns="foo"><Description>1番目</Description></RecRule>
<r:RecRule xmlns:r="foo"><r:Description>1番目</r:Description></r:RecRule>

そのため XPath にて要素を指定する際は、名前空間も含めて記述する必要があります。
MSXML の場合は SelectionNamespaces のプロパティで指定する様です。
https://msdn.microsoft.com/ja-jp/library/ms75604 …

// サンプル
ns = "xmlns:r='http://myschemas.org/Record.set'";
dom.setProperty("SelectionNamespaces", ns);
record = dom.selectSingleNode("//r:RecRule/r:Description");

どうやら MSXML では接頭辞なしで名前空間を指定する方法がないようなので、
適当な接頭辞を決めて XPath を書いてください。
    • good
    • 1
この回答へのお礼

ありがとうございます!
名前空間や接頭辞を入れてXPathを書いていたのですがなかなかうまくいかずに困っていました。XMLのオブジェクト自体に設定を追加しなければならないんですね。読み込んだ時点で自動的に名前空間が認識されているのだと勘違いしていました。

お礼日時:2015/11/30 10:13

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QExcel-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>

すみません、いつも、いろいろな方に助けて頂いていますが、また、初歩的な質問をさせて頂きます。
Excel2007のVBAでXMLの扱いが良くわかっておりません。
以下のプログラムで複数ItemのASINを出力したいのですが、うまくいきません。
XMLがきちんと取得できているのはWireSharkでキャプチャして確認できております。
VBAで表示出力するのがうまくいきません。ご教授方よろしくお願いします。
selectSingleNodeで一つの場合はうまく取り出せています。複数ノードの場合にSelectNodesの使い方に問題がありますでし...続きを読む

Aベストアンサー

とりあえず下記で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

とりあえず下記で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.resolv...続きを読む

QVBでXMLファイルを作ると xmlns= が・・・

VB6でXMLを作成しています。
Dim xmlDoc As New MSXML2.DOMDocument40 'XMLドキュメント
Dim xmlPI As IXMLDOMProcessingInstruction 'XML宣言
Dim node(7) As IXMLDOMNode '要素

Set xmlPI = xmlDoc.appendChild(xmlDoc.createProcessingInstruction("xml", "version= ""1.0"" encoding= ""Shift_JIS"" standalone= ""no"""))
Set node(1) = xmlDoc.appendChild(xmlDoc.createNode(NODE_ELEMENT, "kml", ""))
Set node(2) = node(1).appendChild(xmlDoc.createNode(NODE_ELEMENT, "kmlHeader", ""))
Set node(3) = node(2).appendChild(xmlDoc.createNode(NODE_ELEMENT, "kml_DTD", " kml_Version= 2.8"" kml_FileName=""../DTD/HYB01.dtd"))
以下省略
すると
<kml_DTD xmlns="kml_Version= 2.8" kml_FileName="../DTD/HYB01.dtd" />
"xmlns=" はどうすれば消えますか?お願いします。

VB6でXMLを作成しています。
Dim xmlDoc As New MSXML2.DOMDocument40 'XMLドキュメント
Dim xmlPI As IXMLDOMProcessingInstruction 'XML宣言
Dim node(7) As IXMLDOMNode '要素

Set xmlPI = xmlDoc.appendChild(xmlDoc.createProcessingInstruction("xml", "version= ""1.0"" encoding= ""Shift_JIS"" standalone= ""no"""))
Set node(1) = xmlDoc.appendChild(xmlDoc.createNode(NODE_ELEMENT, "kml", ""))
Set node(2) = node(1).ap...続きを読む

Aベストアンサー

createNodeの第3引数はネームスペースになるのでここに""以外を与えると無条件で『xmlns=』がついてしまうと思います
そこで一度 IXMLDOMElementにNode(3)を代入してこれのsetAttributeを使って属性データを作成すればいいのではないでしょうか

dim tmp as IXMLDOMElement
Set Node(3) = node(2).appendChild(xmlDoc.createNode(NODE_ELEMENT, "kml_DTD", ""))
Set tmp = Node(3)
tmp.setAttribute "kml_version", "2.8"
tmp.setAttribute "kml_FileName", "../DTD/HYB01.dtd"
Set Node(3) = tmp

といった具合です …

QVBAでMSXML2.DOMDocument を使用したい

お世話になります。
下記ソースのようにVBAで「MSXML2.DOMDocument」を使用したいと
思うのですが実行すると
「Dim D As MSXML2.DOMDocument」の箇所で
「コンパイルエラー:ユーザ定義型は定義されていません」
とメッセージがでます。

どのようにすれば「MSXML2.DOMDocument」が使えるのでしょうか?
私は、完全な初心者でありました。何も設定せずに、VBAに下記の
文を入力しました。
解決策と、もし、VBAでDOMを使用する初心者サイトがありましたら
教えて頂ければとおもいます。
よろしくお願いします。

VBAソース--------------------------------------------
Dim D As MSXML2.DOMDocument
Set D = New MSXML2.DOMDocument
D.async = False
If D.Load("C:\SAMPLE.XML") Then
MsgBox "読み込み成功"
Else
MsgBox "読み込み失敗"
End If

お世話になります。
下記ソースのようにVBAで「MSXML2.DOMDocument」を使用したいと
思うのですが実行すると
「Dim D As MSXML2.DOMDocument」の箇所で
「コンパイルエラー:ユーザ定義型は定義されていません」
とメッセージがでます。

どのようにすれば「MSXML2.DOMDocument」が使えるのでしょうか?
私は、完全な初心者でありました。何も設定せずに、VBAに下記の
文を入力しました。
解決策と、もし、VBAでDOMを使用する初心者サイトがありましたら
教えて頂ければとおもいます。
よろしくお願い...続きを読む

Aベストアンサー

ツール→参照設定→Microsoft XML v6.0にチェックを入れる

#事前にMS XML 6.0が必要。
#Windows XP SP3にMSXML v6 SP2が含まれるようだ
#特にSPが書かれていないが,MSXML v6 SP2とバージョンが同じらしい。
http://www.microsoft.com/downloads/details.aspx?familyid=59914795-60C7-4EBE-828D-F28CB457E6E3&displaylang=en
オマケ:
http://blogs.msdn.com/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx

QEXCEL VBAで計算値を四捨五入、切り上げ、切捨てする方法

ネットで探してみたのですが、計算結果を四捨五入して特定のセルを
返すにはどうしたらいいのでしょうか?

Sub hokangosa()

Dim ZPS As Double
Dim ZPOS As Double
Dim DMN As Double
MsgBox (" >>> 補間誤差自動計算 <<< ")
MsgBox (" >>> 初期値入力します <<< ")
ZPS = InputBox(">>> ステップを入力してください<<<")
ZPOS = Sheet1.Cells(22, 4).Value
DMN = ZPOS / ZPS
Sheet1.Cells(23, 6).Value = DMN
End Sub

ここでDMNの値を四捨五入したいです。

またこれとは別に切上げ、切捨ても教えていただけるとありがたいです。

Aベストアンサー

DMN = Application.WorksheetFunction.Round(ZPOS / ZPS, 0)
で、四捨五入
DMN = Application.RoundDown(ZPOS / ZPS, 0)
で切り捨て
DMN = Application.RoundUp(ZPOS / ZPS, 0)
で切り上げです。

引数で、対象桁を変更できます。

QXMLファイル内のデータ(値)を変更するには?

XMLファイルに書かれているデータを変更するプログラムを書きたいのですが、何か良い方法はありますか?
言語は問いません、初歩的な質問かもしれませんがお願いします。

以下valueの部分(数値)を、
value='12'からvalue='13'
のように変更したいのですが、便利な関数などあるでしょうか?
<set name='その1' value='12' />
<set name='その2' value='3' />
<set name='その3' value='5' />
<set name='その4' value='10' />

XMLファイルをオープンして読み込んでから、正規表現などでvalueの値を取得、変更し、ファイルを上書きするのではスマートで無い気がしまして。

Aベストアンサー

Option Explicit On
Option Strict On
Option Compare Binary
' Option Infer Off
'http://support.microsoft.com/kb/317069/en-us
Class Q4095116A

Shared Sub Main

'XPathとかDOMとか組み合わせて使えばいいんじゃないの?
'Javaが関心カテゴリに入っている以上細かい解説はしないで大丈夫だと思うけど。(使ったのはVB.NET)

'Instantiate the XPathDocument class.
Dim xmldoc As New System.Xml.XmlDocument()
xmldoc.Load("./Q4095116-1.xml")

'Instantiate the XPathNavigator class.
Dim nav As System.Xml.XPath.XPathNavigator = xmldoc.CreateNavigator()

'Instantiate the XPathIterator class.
'質問文から読み取れなかったが,どっちだろ。
'ルート要素のhoge要素の子要素のset要素で,かつその要素のname属性が'その1'という値を持つとき、そのvalue属性を列挙するイテレータ
Dim iterator As System.Xml.XPath.XPathNodeIterator = nav.Select("/hoge/set[@name='その1']/@value")

'ルート要素のhoge要素の子要素のset要素で,かつ、その要素のvalue属性が12であるとき、そのそのvalue属性を列挙するイテレータ
'Dim iterator As System.Xml.XPath.XPathNodeIterator = nav.Select("/hoge/set[@value='12']/@value")



Do While iterator.MoveNext
iterator.Current.SetValue("13")
Loop
xmldoc.Save("./Q4095116-1.xml")




End Sub
End Class
========xmlファイル(exeと同じディレクトリに配置したQ4095116-1.xml)===========
<?xml version="1.0" encoding="UTF-8"?>
<hoge>
<!-- ルート要素がないとXMLにならないので。また,上位の要素では名前空間が宣言されていないものとする。-->
<set name="その1" value="12" />
<set name="その2" value="3" />
<set name="その3" value="5" />
<set name="その4" value="10" />
</hoge>

Option Explicit On
Option Strict On
Option Compare Binary
' Option Infer Off
'http://support.microsoft.com/kb/317069/en-us
Class Q4095116A

Shared Sub Main

'XPathとかDOMとか組み合わせて使えばいいんじゃないの?
'Javaが関心カテゴリに入っている以上細かい解説はしないで大丈夫だと思うけど。(使ったのはVB.NET)

'Instantiate the XPathDocument class.
Dim xmldoc As New System.Xml.XmlDocument()
xmldoc.Load("./Q4095116-1.xml")

'Instantiate the XPathNavigator class.
D...続きを読む

QVBA オブジェクトが空かどうか判定する

皆様のお知恵を拝借させてください。

エクセルVBAでオブジェクトを入れる変数を定義し、その変数にオブジェクト
が入っているかどうか検査したいのですがどうしたらいいでしょうか。

例えば---
Dim a As Workbook
If a <> nothing then ←この部分が分からない。このままだとエラー。
処理
End if
---------
環境
エクセル2003
WinXPsp1

Aベストアンサー

もし、aが空だったら
If a Is Nothing Then 

もし、aが空じゃなかったら
If Not a Is Nothing Then

QXMLからデータを取得

いつもお世話になっております。

XMLファイルに含まれたデータの中から、特定のデータを検索するプログラムを作りたいと思っております。

<AAA Name="テスト">
   <BBB x="2" y="2"></BBB>
   <CCC Num="0001"></CCC>
   <CCC Num="0002"></CCC>
</AAA>
XMLデータの形式は↑みたいな感じで、これが100以上あり、CCCタグは0~5個までです。

フォームにテキストボックスを配置し、そこに検索したい語句を入れ、
AAAタグのNameの中身と合致したら、BBB、CCCの属性をすべて取得して表示するということをしたいのですが、
どうにも上手くいきません。

VB2008を使用しております。
方法をご存知の方、ご教授ください……orz

Aベストアンサー

a_navi.Select("//AAA[@Name='test']")
で AAAタグの検索条件を増やさないのであれば

xml_data = a_navi.Select("//AAA[@Name='test']")
while xml_data.MoveNext
  Dim xmldoc As New Xml.XmlDocument
  ' XMLDocumentに 選択されたCurrentのOuterXmlを与えれば
  ' 自前で XML形式の体裁を整える必要がありません
  xmldoc.loadXML( xml_data.Current.OuterXml)
  ' StringReaderにも OuterXmlで与えます
  a_xml = new Xml.XmlTextReader(New IO.StringReader(xml_data.DocumentElement.OuterXml))
  while a_xml.Read
    If a_xml.NodeType = XmlNodeType.Element Then
      Select Case a_xml.LocalName
        ' AAAタグ用の分岐を定義
        Case "AAA"
          Console.WriteLine("aaa:" & a_xml.GetAttribute("age") & "," & a_xml.GetAttribute("id"))
        Case "BBB"
          Console.WriteLine("bbb:" & a_xml.GetAttribute(0) & "," & a_xml.GetAttribute(1))
        Case "CCC"
          Console.WriteLine("ccc:" & a_xml.GetAttribute(0))
      End Select
    End If
  end while
end while

といった具合でよさそうですよ

a_navi.Select("//AAA[@Name='test']")
で AAAタグの検索条件を増やさないのであれば

xml_data = a_navi.Select("//AAA[@Name='test']")
while xml_data.MoveNext
  Dim xmldoc As New Xml.XmlDocument
  ' XMLDocumentに 選択されたCurrentのOuterXmlを与えれば
  ' 自前で XML形式の体裁を整える必要がありません
  xmldoc.loadXML( xml_data.Current.OuterXml)
  ' StringReaderにも OuterXmlで与えます
  a_xml = new Xml.XmlTextReader(New IO.StringReader(xml_data.DocumentElement...続きを読む

QVBSでxmlの値を書き換えたい

お世話になります。
VBScriptで作成しています。

A.xmlの「sx」の値を全て200にしたいと思っております。
A.xmlの値を抜き取って、OKフォルダに複製する処理は
作ったのですが、どのようにして、sxを指定・その中の値を
変更するのかわかりません。

お手数ですが、ご教授お願いいたします。

------------------A.xml----------------------------
<?xml version="1.0" encoding="UTF-8"?>
<links>
<link id="0" name="" title="">
<sx>145</sx>
<sy>142</sy>
</link>
<link id="1" name="" title="">
<sx>495</sx>
<sy>142</sy>
</link>
<link id="2" name="" title="">
<sx>155</sx>
<sy>510</sy>
</link>
</links>

---------------------------------------------------
------スクリプト------------------------------------------------
Set Fso = CreateObject("Scripting.FileSystemObject")
Set objXML = CreateObject("Msxml2.DOMDocument.3.0")

' カレントディレクトリ
str = WScript.ScriptFullName
Set obj = Fso.GetFile( str )
Set obj = obj.ParentFolder
str = obj.Path

' XML を読み込み
objXML.load( str & "\A.xml" )

**********************************************************
'''ここで、sxの属性の値を変更したい
**********************************************************

' XML を保存
objXML.save( str & "\OK\A.xml" )
------------------------------------------------------

お世話になります。
VBScriptで作成しています。

A.xmlの「sx」の値を全て200にしたいと思っております。
A.xmlの値を抜き取って、OKフォルダに複製する処理は
作ったのですが、どのようにして、sxを指定・その中の値を
変更するのかわかりません。

お手数ですが、ご教授お願いいたします。

------------------A.xml----------------------------
<?xml version="1.0" encoding="UTF-8"?>
<links>
<link id="0" name="" title="">
<sx>145</sx>
<sy>142</sy>
</link>
<link id="1" name="" title...続きを読む

Aベストアンサー

SelectNodesを使って抽出を行えば いいと思いますよ

dim objList, objNode

Set objList = objXml.SelectNodes("//links/link/sx")
for each objNode in objList
  objNode.Text = "200"
next

といった具合です

Qタグの有無の判定

みなさん、初めまして。

今、XSLTでXMLファイルをJavaファイルに変換するxslファイルを
書いているのですが質問のタイトルの通りタグの有無を判定して処理
を行いたいのですが、どのようにすれば可能でしょうか?

例えば、XMLファイル中に

<work>
<value></value>
</work>
<work>
<value>test</value>
<work>

上記のような内容があった場合にのタグの値の有無で処理を行うには

<xsl:choose>
<xsl:when test="value=''">hogehoge</xsl:when>
<xsl:otherwise>fugafuga</xsl:otherwise>
</xsl:choose>

とすれば可能だと思うのですが(もっと簡単な方法もあるかも
しれませんが・・・)、workタグの中にvalueタグが無かった
場合にAという処理をし、タグがある場合にはBと言う処理を
行うという事をしたいのです。

それではよろしくお願い致します。

みなさん、初めまして。

今、XSLTでXMLファイルをJavaファイルに変換するxslファイルを
書いているのですが質問のタイトルの通りタグの有無を判定して処理
を行いたいのですが、どのようにすれば可能でしょうか?

例えば、XMLファイル中に

<work>
<value></value>
</work>
<work>
<value>test</value>
<work>

上記のような内容があった場合にのタグの値の有無で処理を行うには

<xsl:choose>
<xsl:when test="value=''">hogehoge</xsl:when>
<xsl:otherwise>fugafuga</xsl:otherwi...続きを読む

Aベストアンサー

タグの値の有無(空か否か)を判断したいのであれば
<xsl:when test="value=''">hogehoge</xsl:when>
でいいでしょう

タグの有無を判断するなら
<xsl:when test="count(value)=0">hogehoge</xsl:when>
ですね



<value></value>のような空要素と、タグが無いというのは同義語ではないです。どちらを指していたのでしょうか?

QMAX値を条件にデータを取得するには?

SQL文で困っています。
ご教授下さい。


下記のようなデータがあった場合、それぞれの区分毎に
年月が最大(最新)のデータを取得したいです。
(実際には1レコードにその他項目があり、それらも取得します。)
<検索対象データ>
区分 年月   金額
-----------------------------
A   200412  600
A   200503  560
B   200311  600
B   200508  1000
B   200504  560
C   200508  400
C   200301  1100


<取得したいデータ>

区分 年月   金額
-----------------------------
A   200503  560
B   200508  1000
C   200508  400

よろしくお願いします。

Aベストアンサー

テーブル名をXXXとすると次のようなSQLでよいと思います。(最善の方法かどうかは自信がないですが)

select B.* from (select 区分, max(年月) as 年月 from XXX group by 区分) As A
inner join XXX as B on A.区分 = B.区分 and A.年月 = B.年月
order by B.区分


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング