いつも勉強させていただいています。
ありがとうございます。
Excel2007上のVBAで下記のようなXML処理を行いたいのですが、
求める結果と違う処理がされてしまいます。
何卒、ご指導をお願いできませんでしょうか・・・?
■やりたいこと(処理前)
<?xml version="1.0" encoding="UTF-8" ?>
<タグ1 属性11="abc" 属性12="w">
<タグ2>
<タグ3 属性31="1">
<タグ5 属性51="abc"/> '←[タグ5]の[属性51]が[1000]だったら追加処理
<タグ5 属性52="def"/>
</タグ3>
<タグ4 属性41="2">
<タグ5 属性51="1000"/> '←[タグ5]の[属性51]が[1000]だったら追加処理
<タグ5 属性52="1100"/>
</タグ4>
</タグ2>
</タグ1>
↓
■やりたいこと(処理後)
<?xml version="1.0" encoding="UTF-8" ?>
<タグ1 属性11="abc" 属性12="w">
<タグ2>
<タグ3 属性31="1">
<タグ5 属性51="abc"/> '←[タグ5]の[属性51]が[1000]だったら追加処理
<タグ5 属性52="def"/>
</タグ3>
<タグ4 属性41="2">
<タグ5 属性51="1000"/> '←[タグ5]の[属性51]が[1000]だったら追加処理
<タグ5 属性52="1100"/>
<タグ6 属性61="abcdef"/> '←ここに追加したい
</タグ4>
</タグ2>
</タグ1>
■求める結果と違う処理
Sub Macro1
Dim DomXmlDocument As MSXML2.DOMDocument
Set DomXmlDocument = New MSXML2.DOMDocument
DomXmlDocument.Load("test.xml")
Dim namedNodeMap As IXMLDOMNamedNodeMap
Dim MyNode As IXMLDOMNode
For Each Node In DomXmlDocument.SelectNodes("//タグ5/@*")
If Node.NodeValue = "1000" Then
Set MyNode = DomXmlDocument.createNode(2, "属性61", "abcdef")
Set namedNodeMap = DomXmlDocument.DocumentElement.ChildNodes.Item(4).Attributes
namedNodeMap.setNamedItem MyNode
End If
Next
DomXmlDocument.Save ("test_after.xml")
End Sub
> <タグ5 属性51="abc"/> '←[タグ5]の[属性51]が[1000]だったら追加処理
コメントの意図ならば、「'」よりも「<!-- -->」の方が良いかも。
本題とは無関係ですけれども。
> Set MyNode = DomXmlDocument.createNode(2, "属性61", "abcdef")
第3引数に属性値を指定しているようですが、そこにくるのは名前空間の指定ですよ。
また、「2」のようなマジックナンバーではなく、「NODE_ATTRIBUTE」などの定数を使うようにしましょう。
それと、肝心の「<タグ6>」の要素ノードを作るためのコードも抜け落ちているようです。
> Set namedNodeMap = DomXmlDocument.DocumentElement.ChildNodes.Item(4).Attributes
これはエラーになりますね。
load 前の preserveWhiteSpace プロパティの値にもよりますが、
preserveWhiteSpace = False で読み込んでいたとしたら、
『DomXmlDocument.DocumentElement.ChildNodes』の .length は 1 ですよね。
タグ2ノードしか返さないはずなので、.Item(4) はエラーです。
preserveWhiteSpace = True であったとしても、.lengh は 3 です。
「タグ1 と タグ2 の間のテキストノード」と、「タグ2 の要素ノード」と
「タグ2 の終わりからタグ1 の間のテキストノード」だけであって、
『4』は存在しません。
> ■やりたいこと(処理後)
私が書くとしたら、こうかな…。
Dim DomXmlDocument As MSXML2.DOMDocument
Set DomXmlDocument = New MSXML2.DOMDocument
DomXmlDocument.async = False
DomXmlDocument.preserveWhiteSpace = True
DomXmlDocument.Load "test.xml"
DomXmlDocument.setProperty "SelectionLanguage", "XPath"
Dim Node As IXMLDOMNode
For Each Node In DomXmlDocument.selectNodes("//*[タグ5/@属性51='1000']")
Node.insertBefore(DomXmlDocument.createElement("タグ6"), Nothing).Attributes.setNamedItem(DomXmlDocument.createAttribute("属性61")).nodeValue = "abcdef"
Next
DomXmlDocument.save "test_after.xml"
迅速かつ確実そして懇切丁寧な回答をありがとうございます。
意図した動作が確認できました!