DOBON.NET DOBON.NETプログラミング掲示板過去ログ

DOMによるXMLの参照

  • 題名: DOMによるXMLの参照
  • 著者: チャロ
  • 日時: 2009/05/01 1:54:49
  • ID: 24493
  • この記事の返信元:
    • (なし)
  • この記事への返信:
  • ツリーを表示
環境/言語:[Excel VBA]
分類:[VB6以前]

以下の様なXMLが有るのですがMsxml2.DOMDocument.4.0を用いて
ExcelVBA内で次の事を実現したいのですが、なかなか要領を得ません。

1. <ModelElement ElementName="R01" ElementId="PG_PS856593570"
  のレコードを検索する。

2. <ModelElement ElementNameの値が
  <Field Name="TypeName" Valueの値が"コントロール"の時の
  <Field Name="ElementId" Valueの値を取得・書換えをしたい。

3. 2.で該当する物が無かった場合<Record>タグセットを追加したい等を
  行いたい場合、どの様に記述すればよいのでしょうか?
  何方か御指導下さいますよう、よろしくお願いいたします。

<AAAAA>
<ModelElement ElementName="・・・・・
・・・・・
・・・・・
・・・・・
</ModelElement>

<ModelElement ElementName="R01" ElementId="PG_PS856593570" TypeID="PG_PS1317908445">
<Attribute AttributeName="・・・・・">
・・・・・
</Attribute>

<Attribute AttributeName="コントロール">
<Record>
<Field Name="ValueParentId" Value="0"/>
<Field Name="ElementName" Value="C01"/>
<Field Name="ElementId" Value="PG_PS1207577013"/>
<Field Name="TypeName" Value="コントロール"/>
<Field Name="TypeID" Value="PG_PS1318551550"/>
</Record>
<Record>
<Field Name="ValueParentId" Value="0"/>
<Field Name="ElementName" Value="C02"/>
<Field Name="ElementId" Value="PG_PS1372982226"/>
<Field Name="TypeName" Value="コントロール"/>
<Field Name="TypeID" Value="PG_PS1318551550"/>
</Record>
<Record>
<Field Name="ValueParentId" Value="0"/>
<Field Name="ElementName" Value="C05"/>
<Field Name="ElementId" Value="PG_PS1217594053"/>
<Field Name="TypeName" Value="コントロール"/>
<Field Name="TypeID" Value="PG_PS1318551550"/>
</Record>

<Record>
<Field Name="ValueParentId" Value="・・・・・"/>
<Field Name="ElementName" Value="・・・・・"/>
<Field Name="ElementId" Value="・・・・・"/>
<Field Name="TypeName" Value="・・・・・"/>
<Field Name="TypeID" Value="・・・・・"/>
</Record>

</Attribute>
</ModelElement>

<ModelElement ElementName="・・・・・
・・・・・
・・・・・
・・・・・
</ModelElement>


</AAAAA>
■No24493に返信(チャロさんの記事)
> 1. <ModelElement ElementName="R01" ElementId="PG_PS856593570"
>   のレコードを検索する。
レコードというのは、XML の「要素ノード」の事でしょうか?

> 2. <ModelElement ElementNameの値が
>   <Field Name="TypeName" Valueの値が"コントロール"の時の
>   <Field Name="ElementId" Valueの値を取得・書換えをしたい。
この場合の Value は、「属性ノード」ですね。

方法は幾つかありますが、MSXML では、nodeValue プロパティで
読み書きするのが簡単でしょう。

> 3. 2.で該当する物が無かった場合<Record>タグセットを追加したい等を
>   行いたい場合、どの様に記述すればよいのでしょうか?
>   何方か御指導下さいますよう、よろしくお願いいたします。
存在チェックは、SelectNodes や SelectSingleNode メソッドで行えます。
見つからなかった場合には、createElement メソッド等を使ってノードを生成し、
その追加したノードを、insertBefore メソッド等で追加してやれば OK かと。
魔界の仮面弁士 様 御指導有難うございます。

以下の様な簡単なXMLですと、幾つかサンプルを見つける事が出来るのですが。
<AAAAA>
<a>123</a>
<b>abc</b>
</AAAAA>

前述の様なXMLですと参照をする具体的なサンプルを見つける事が出来ません
どなたか良いサイト等をご存知の方がいらっしゃいましたら教えて下さい。
2009/05/01(Fri) 20:16:45 編集(投稿者)

■No24494に追記(魔界の仮面弁士の記事)

設問条件に、Attribute の扱いについて書かれていないのと、
条件3.で生成する Record 以下のスキーマが良く分からなかったので、
とりあえず条件2.までのサンプルを書いてみました。

なお、XML 名前空間の記載については考慮していません。

'---------------------------------------

'MSXML2.6/3.0 の初期設定は XSLPattern だが、XPath も使用可能
'MSXML4.0/5.0/6.0 の初期設定は XPath 言語で、XSLPattern は使用不可
'http://support.microsoft.com/kb/288913/en-us
'http://msdn.microsoft.com/en-us/library/ms754679.aspx
doc.setProperty "SelectionLanguage", "XPath"

'1. <ModelElement ElementName="R01" ElementId="PG_PS856593570"
'   のレコードを検索する。
query = "/AAAAA/ModelElement[@ElementName='R01' and @ElementId='PG_PS856593570']"
Set nodeModelElement = doc.selectSingleNode(query)
If nodeModelElement Is Nothing Then
 MsgBox "見つかりませんでした。", vbInformation
 Exit Sub
End If


'2. <ModelElement ElementNameの値が
'   <Field Name="TypeName" Valueの値が"コントロール"の時の
'   <Field Name="ElementId" Valueの値を取得・書換えをしたい。
query = "Attribute/Record/Field[@Name='TypeName' and @Value='コントロール']/../Field[@Name='ElementId']/.."

Set nodes = nodeModelElement.selectNodes(query)
For Each nodeRecord In nodes
 Set attNode = nodeRecord.selectSingleNode("Field[@Name='ElementId']/@Value")
 oldValue = attNode.nodeValue
 newValue = InputBox("新しい ElementId 値を入れてください。", ThisWorkbook.Name, oldValue)
 If StrPtr(newValue) <> 0 And attNode.nodeValue <> newValue Then
  attNode.nodeValue = newValue
 End If
Next
If nodes.length = 0 Then
 MsgBox "登録されていません。"
 '3. 2.で該当する物が無かった場合


 Exit Sub
End If
  • 題名: Re[3]: DOMによるXMLの参照
  • 著者: 魔界の仮面弁士
  • 日時: 2009/05/01 16:30:49
  • ID: 24500
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
2009/05/01(Fri) 16:36:53 編集(投稿者)

■No24499に追記(魔界の仮面弁士の記事)
> ■No24494に追記(魔界の仮面弁士の記事)
> 条件3.で生成する Record 以下のスキーマが良く分からなかったので、
> とりあえず条件2.までのサンプルを書いてみました。
> '---------------------------------------
> If nodes.length = 0 Then
>  MsgBox "登録されていません。"
>  '3. 2.で該当する物が無かった場合
>  Exit Sub
> End If


条件3.のサンプル。

'Nothing を指定すると、子要素の末尾に追加されます。
'別の位置に挿入したい場合は、挿入先の子ノードを指定してください。
Set nodeAttribute = nodeModelElement.insertBefore(doc.createElement("Attribute"), Nothing)

Set nodeRecord = nodeModelElement.appendChild(doc.createElement("Record"))

With nodeRecord.appendChild(doc.createElement("Field")).attributes
 .setNamedItem(doc.createAttribute("Name")).nodeValue = "ValueParentId"
 .setNamedItem(doc.createAttribute("Value")).nodeValue = "0"
End With
With nodeRecord.appendChild(doc.createElement("Field")).attributes
 .setNamedItem(doc.createAttribute("Name")).nodeValue = "ElementName"
 .setNamedItem(doc.createAttribute("Value")).nodeValue = "C99"
End With
With nodeRecord.appendChild(doc.createElement("Field")).attributes
 .setNamedItem(doc.createAttribute("Name")).nodeValue = "ElementId"
 .setNamedItem(doc.createAttribute("Value")).nodeValue = "・・・・・"
End With
With nodeRecord.appendChild(doc.createElement("Field")).attributes
 .setNamedItem(doc.createAttribute("Name")).nodeValue = "TypeName"
 .setNamedItem(doc.createAttribute("Value")).nodeValue = "コントロール"
End With
With nodeRecord.appendChild(doc.createElement("Field")).attributes
 .setNamedItem(doc.createAttribute("Name")).nodeValue = "TypeID"
 .setNamedItem(doc.createAttribute("Value")).nodeValue = "・・・・・"
End With
  • 題名: Re[3]: DOMによるXMLの参照
  • 著者: チャロ
  • 日時: 2009/05/08 17:41:04
  • ID: 24518
  • この記事の返信元:
  • この記事への返信:
    • (なし)
  • ツリーを表示
魔界の仮面弁士 様

 御指導有難うございます。

おかげで解決する事が出来ました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板