[リストへもどる]
一括表示

投稿時間:2004/07/18(Sun) 19:16
投稿者名:tak
Eメール:
URL :
タイトル:
ListViewのNodeをXMLより取得したいのですが
こんにちは。いつも参考にさせて頂いています。今回はどうしてもわからない事があるので投稿させてもらいます。

root
└-E:\データ\
  └-クライアント
   └+in\
   └+out\
  └-サーバ
   └+in\
   └+out\
※-はディレクトリが閉じている状態です。
※+はディレクトリが開いている状態です。

今回、上記のようにListViewで可変のディレクトリ構造を表示する処理を行おうとしています。
可変というのは「クライアント」、「サーバ」配下に「in」、「out」以外のフォルダが存在できることを示します。

これを実現する為に色々調べて、マイクロソフトの技術者ページよりXMLよりノード情報を取得する方法があり、これを利用しようと思っています。これならディレクトリ構造が変化した時、XMLファイルだけを上書きしてあげればいいので・・。
ですが、まずタグに「サーバ」や「:\」など全角や特殊文字は使えないようです。
ですので、以下のようにできれば全角、特殊文字をノードのテキストに表示できるかなと考えていますが、どうもうまくいきません・・。

<id-client>id="クライアント"
</id-client>

他の方法でももちろん結構ですが、ノードに全角テキストや特殊文字を表示させることは可能でしょうか??
ご存知のかたご教授お願いします。

投稿時間:2004/07/18(Sun) 20:43
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re: ListViewのNodeをXMLより取得したいのですが
テキストを属性値として盛り込むとか。


<?xml version="1.0" encoding="Shift_JIS"?>
<node text="root">
  <node text="E:\データ\">
    <node text="クライアント">
      <node text="in\">
        <node text="child1"/>
        <node text="child2"/>
      </node>
      <node text="out\">
        <node text="child3"/>
      </node>
    </node>
    <node text="サーバ">
      <node text="in\">
        <node text="child4"/>
      </node>
      <node text="out\">
        <node text="child5"/>
      </node>
    </node>
  </node>
</node>

投稿時間:2004/07/18(Sun) 21:57
投稿者名:tak
Eメール:
URL :
タイトル:
Re^2: ListViewのNodeをXMLより取得したいのですが
>魔界の仮面弁士さん
レスありがとうございます。
ご教授いただいたXMLファイルで現状のロジックを流すと以下の結果となりました。
階層は思い通りになっていますが、ノードのテキストがすべて「node」となっていました。
<node text>タグのテキストを取得する方法がわかりませんでした・・。
よろしければ取得方法を教えていただけませんか??

node
└-node
  └-node
    └-node
      └-node
      └-node
    └-node
      └-node
  └-node
    └-node
     └-node
    └-node
     └-node




一応現状のソースを載せて置きます。

Option Explicit
   Dim XMLDoc As MSXML.DOMDocument
Private Sub Form_Load()    
    Set XMLDoc = New DOMDocument
    XMLDoc.async = False
    XMLDoc.Load Text1.Text
    
    If XMLDoc.parseError.errorCode = 0 Then
        If XMLDoc.readyState = 4 Then
            TreeView1.Nodes.Clear
            AddNode XMLDoc.documentElement
        End If
    Else
        MsgBox XMLDoc.parseError.reason & vbCrLf & _
        XMLDoc.parseError.Line & vbCrLf & _
        XMLDoc.parseError.srcText
    End If
End Sub
Private Sub AddNode(ByRef XML_Node As IXMLDOMNode, _
                    Optional ByRef TreeNode As Node)
    Dim xNode As Node
    Dim xNodeList As IXMLDOMNodeList
    Dim i As Long
    
    If TreeNode Is Nothing Then
        Set xNode = TreeView1.Nodes.Add
    Else
        Set xNode = TreeView1.Nodes.Add(TreeNode, tvwChild)
    End If
    
    xNode.Expanded = True
    xNode.Text = XML_Node.nodeName
    
    If xNode.Text = "#text" Then
        xNode.Text = XML_Node.nodeTypedValue
    Else
        xNode.Text = xNode.Text
    End If
    
    Set xNodeList = XML_Node.childNodes
    For i = 0 To xNodeList.length - 1
        AddNode xNodeList.Item(i), xNode
    Next
End Sub

投稿時間:2004/07/19(Mon) 23:11
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
Re^3: ListViewのNodeをXMLより取得したいのですが
> ご教授いただいたXMLファイルで現状のロジックを流すと以下の結果となりました。
> 階層は思い通りになっていますが、ノードのテキストがすべて「node」となっていました。

要素ノード中の属性ノードを取得するには、
  XMLNode.attributes.getNamedItem("text").nodeValue
のような構文を使えます。

また、XPath式を御存知なら、
  XMLNode.selectSingleNode(@text").nodeValue
のように、selectSingleNode/SelectNodesメソッドを使うのも便利かと。


> 一応現状のソースを載せて置きます。
例えば、こんな感じで。

Private Sub Form_Load()
    With New DOMDocument
        .async = False
        If .loadXML(Text1.Text) Then
            FillNode TreeView1.Nodes.Add(), .documentElement
        End If
    End With
End Sub

Private Sub FillNode(ByVal TreeNode As Node, ByVal XMLNode As IXMLDOMNode)
    TreeNode.Text = XMLNode.selectSingleNode("@text").nodeValue
    TreeNode.Expanded = True
    Dim Child As IXMLDOMNode
    For Each Child In XMLNode.childNodes
        FillNode TreeView1.Nodes.Add(TreeNode, tvwChild), Child
    Next
End Sub


これを応用すれば、テキスト以外にも「ノードの画像」「ノードを開いておくか閉じておくか」
「ノードの文字色」といった情報も、XMLデータに含めておくことができるかと。

投稿時間:2004/07/21(Wed) 00:58
投稿者名:tak
Eメール:
URL :
タイトル:
解決!ListViewのNodeをXMLより取得したいのですが
>魔界の仮面弁士さん
お返事ありがとうございます!

> 要素ノード中の属性ノードを取得するには、
>   XMLNode.attributes.getNamedItem("text").nodeValue
> のような構文を使えます。
なるほど。属性を取得する方法もちゃんと提供されていたのですね。
当然といえば当然なのでしょうが、昨日いろいろいじってたのですが、気がつきませんでした・・。
残念ながらXPath式はまったく存じませんので、やはりXMLでいこうと思います。

サンプルのソースまでご提供いただきありがとうございます。
「ノードを開いておくか閉じておくか」という属性も追加して、ソースの一部も現行のソースに取り入れて、満足いく結果が出せました!

本当に助かりました。どうもありがとうございましたm(_ _)m

投稿時間:2004/07/21(Wed) 10:15
投稿者名:魔界の仮面弁士
Eメール:
URL :
タイトル:
蛇足: XPathの使い方
> 残念ながらXPath式はまったく存じませんので、やはりXMLでいこうと思います。

「やはりXMLで」という発言から察するに、どうやら、
XPath式に関して何か誤解がありそうなので、補足しておきます。


XPathとは、「XMLデータを検索/照会するための構文」の一つです。
データベースでいうところのSQLに相当します。

深い階層、複雑な階層などを簡単に取得出来ますし、XSLTでも使えますので、
XMLを扱うのであれば、覚えておくと便利だと思いますよ。


------------

MSXMLにてXPath式を使った検索を行うには、最初に、
  .setProperty "SelectionLanguage", "XPath"
を宣言してから、selectSingleNode または selectNodes を呼び出します。

なお、selectSingleNodeメソッドは、最初に一致するノードを返します。
selectNodesメソッドは、一致するノードをコレクションとして返します。



具体例で言えば、
  .setProperty "SelectionLanguage", "XPath"
  Dim XMLNodeList As IXMLDOMNodeList
  Set XMLNodeList = .selectNodes("//*[@*='in\']")
のようにすると、
  『値が"in\"である属性を持つノード』
という意味になります。
( [〜] の部分は述部といって、検索条件を指定する部分です)


この場合、先の No.9679 で提示したサンプルでいえば、
   <node text="in\">
     <node text="child1"/>
     <node text="child2"/>
   </node>
と、
   <node text="in\">
     <node text="child4"/>
   </node>
という、2件のノードセットを返すことになります。


この時に、さらに「子要素が2個の物」という条件を追加しておき、
  Set XMLNodeList = .selectNodes("//node[@text='in\' and count(*)=2]")
などと書く事もできます。(この場合、前者のノードセットだけが取得されます)


なお、上記の count() というのは、XPath 関数の一つです。他にも、
   Set XMLNodeList = .selectNodes("//*[starts-with(@*,'ク')]")
のようにして、『値が"ク"で始まる属性を持つノード』を探す事もできます。

投稿時間:2004/07/21(Wed) 18:50
投稿者名:tak
Eメール:
URL :
タイトル:
Re: 蛇足: XPathの使い方
>魔界の仮面弁士さん
おっしゃるとおりXpath式について誤解していました。

> データベースでいうところのSQLに相当します。
>   Set XMLNodeList = .selectNodes("//node[@text='in\' and count(*)=2]")
なるほど。SQLですか。簡潔な説明で理解できました。
階層を取得するだけのためにXMLを採用したのですが、これは思いがけない収穫です。
.NETでもiniファイルの変わりにxmlを使用することがあるようで、単なる設定ファイルとして使う
だけと考えていましたが、すごい便利ですよね。
今回はそこまでの仕様ではないのでxpath式は使う機会がないかも知れませんが、覚えておきます。

度々のご指導ありがとうございましたm(_ _)m