XML reading more details
XML reading more details
XML reading more details
XML reading more details
XML reading more details
XML reading more details XML reading more details XML reading more details XML reading more details XML reading more details XML reading more details XML reading more details XML reading more details
XML reading more details XML reading more details
XML reading more details
Go Back  Xtreme Visual Basic Talk > > > XML reading more details


Reply
 
Thread Tools Display Modes
  #21  
Old 08-13-2008, 09:21 AM
AtmaWeapon's Avatar
AtmaWeaponXML reading more details AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default


It might help if, instead of blindly using my variable names and program structure like a cargo cultist, you'd modify the logic and tweak the variable names to fit your scenario. aliceNode made sense in my original example because it was supposed to hold an XML node that referred to the person "Alice". It makes no sense to hold "Either Nothing or a node that matches the user's search" in such a specific variable name.

Take a look at this rewrite of your code with descriptive variable names and see if you can't find the logic error:
Code:
Dim m_xmld As New XmlDocument()
m_xmld.Load("..\..\test.xml")
Dim roleNodes As XmlNodeList = m_xmld.SelectNodes("docuvault_settings/role_list/role")
For Each roleNode As XmlNode In roleNodes

    Dim userNode As XmlNode = roleNode.SelectSingleNode("members/user[@account_name='akincaid']")

    If userNode IsNot Nothing Then
        Dim Name As String = roleNode.Attributes.GetNamedItem("obj_name").Value
        Dim Permission As String = roleNode.Attributes.GetNamedItem("permission").Value
    End If
Next
Hint: do roles have permission attributes? Do users have obj_name attributes? You'll have to get these values from the node that has the value.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #22  
Old 08-13-2008, 09:50 AM
vb2008 vb2008 is offline
Regular
 
Join Date: Jan 2008
Posts: 88
Default

I think I understand what you are saying... That I need to navigate down to users to get the permissions attribute but thats just it... I am not exactly sure how to do that.

I would think it would be something like....

Code:
     m_node.SelectSingleNode("members/user")
                Permission = m_node.Attributes.GetNamedItem("permission").Value
The reason I say members/user is because I would think this....
Code:
 m_nodelist = m_xmld.SelectNodes("docuvault_settings/role_list/role")
Would have me in the area I want so I would just go down from there... I guess I am not even sure where I am going wrong.

It seems like all the examples I find online do not dig very deep into a XML file to see how it moves around.
Reply With Quote
  #23  
Old 08-13-2008, 12:11 PM
AtmaWeapon's Avatar
AtmaWeaponXML reading more details AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

Look at my code and think.

roleNode is the current role node. userNode is the current user node. You want an attribute from each one. How would you go about getting the value of a node's attribute? (Hint: You've done it several times already!)
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #24  
Old 08-13-2008, 01:25 PM
vb2008 vb2008 is offline
Regular
 
Join Date: Jan 2008
Posts: 88
Default

I still am not getting it.... Nothing I try seems to work.

Code:
For Each m_node In m_nodelist
            Dim RoleNode As XmlNode = m_node.SelectSingleNode("members/user[@account_name='" & Role_Search_Value_1.Text & "']")

            If RoleNode IsNot Nothing Then
                Name = m_node.Attributes.GetNamedItem("obj_name").Value
                Permission = m_node.Attributes.GetNamedItem("members/user[@permission]").Value

                Report_Screen.Rows.Add(New String() {Name, Role_Search_Value_1.Text, Permission})

                ' Set Grid
                Role_Report_Grid.DataSource = Report_Screen
                Role_Report_Grid.Columns("Role Name").Width = 350
                Role_Report_Grid.Columns("Match Criteria").Width = 300
                Role_Report_Grid.Columns("Permission").Width = 50

            Else
                ' Do nothing
            End If
        Next
If I am sitting at the RoleNod then it seems that this....
Code:
Permission = m_node.Attributes.GetNamedItem("members/user[@permission]").Value
Would get me where I want be.

Code:
<docuvault_settings>
	<role_list>
		<role obj_name="Logistics" >
			<role_type>master_role</role_type>
			<members>
				<user domain_name="GFSPROD" account_name="aclippert" permission="000F" />
I do not understand why it does not.
Reply With Quote
  #25  
Old 08-13-2008, 02:11 PM
AtmaWeapon's Avatar
AtmaWeaponXML reading more details AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

Let's try a different approach and see if it helps you understand. I'm going to ask some questions. Think about them, then post your answers.

What kind of node would this return?
Dim RoleNode As XmlNode = m_node.SelectSingleNode("members/user[@account_name='" & Role_Search_Value_1.Text & "']")
Let's say the search term is "asdf". This will give you the following XPath:
members/user[@account_name='asdf']

Is this going to be a <role> element like the variable name implies, or something else entirely? Think about what the XPath is saying to retrieve.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #26  
Old 08-13-2008, 02:12 PM
AtmaWeapon's Avatar
AtmaWeaponXML reading more details AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

Also I forgot this one:

Permission = m_node.Attributes.GetNamedItem("members/user[@permission]").ValueWhat do you think this is asking the node for? Does the GetNamedItem method expect XPath, or the name of an item?
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #27  
Old 08-14-2008, 07:09 AM
vb2008 vb2008 is offline
Regular
 
Join Date: Jan 2008
Posts: 88
Default

No the first part here....
Dim RoleNode As XmlNode = m_node.SelectSingleNode("members/user[@account_name='" & Role_Search_Value_1.Text & "']")
I would think is working in the role element.

But I would think that this....
members/user[@account_name='asdf']
Would be in the members element.

It's the whole structure that I am not gettings and I can not seem to find any good web sites that go through it.


Quote:
Originally Posted by AtmaWeapon View Post
Let's try a different approach and see if it helps you understand. I'm going to ask some questions. Think about them, then post your answers.

What kind of node would this return?
Dim RoleNode As XmlNode = m_node.SelectSingleNode("members/user[@account_name='" & Role_Search_Value_1.Text & "']")
Let's say the search term is "asdf". This will give you the following XPath:
members/user[@account_name='asdf']

Is this going to be a <role> element like the variable name implies, or something else entirely? Think about what the XPath is saying to retrieve.
Reply With Quote
  #28  
Old 08-14-2008, 07:10 AM
vb2008 vb2008 is offline
Regular
 
Join Date: Jan 2008
Posts: 88
Default

I thought it was asking for the value of the permission but I guess I am wrong?

Quote:
Originally Posted by AtmaWeapon View Post
Also I forgot this one:

Permission = m_node.Attributes.GetNamedItem("members/user[@permission]").ValueWhat do you think this is asking the node for? Does the GetNamedItem method expect XPath, or the name of an item?
Reply With Quote
  #29  
Old 08-14-2008, 07:35 AM
vb2008 vb2008 is offline
Regular
 
Join Date: Jan 2008
Posts: 88
Default

So is this even close?

Code:
 
         m_xmld = New XmlDocument()
        m_xmld.Load("C:\Share\GR_Prd_DV1_roles.xml")
        m_nodelist = m_xmld.SelectNodes("docuvault_settings/role_list/role")

        For Each m_node In m_nodelist
            Dim RoleNode As XmlNode = m_node.SelectSingleNode("members/user[@account_name='" & Role_Search_Value_1.Text & "']")

            If RoleNode IsNot Nothing Then

                Name = m_node.Attributes.GetNamedItem("obj_name").Value

                m_xmld.SelectNodes("docuvault_settings/role_list/members")
                Permission = m_node.Attributes.GetNamedItem("permission").Value
Reply With Quote
  #30  
Old 08-14-2008, 08:08 AM
AtmaWeapon's Avatar
AtmaWeaponXML reading more details AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

Quote:
Originally Posted by vb2008 View Post
No the first part here....
Dim RoleNode As XmlNode = m_node.SelectSingleNode("members/user[@account_name='" & Role_Search_Value_1.Text & "']")
I would think is working in the role element.
Wrong. The rightmost element of an XPath statement is the node it will select. You can visualize some XPath statements by making a pseudo-XML file based on the path. Here's what you're working with:

m_Node is: docuvault_settings/role_list/role
Code:
<docuvault_settings>
    <role_list>
        <role>
This is the XPath that selects a role element.

RoleNode is: m_node.SelectSingleNode(members/user[@account_name='searchValue'])
Code:
...
<role>
    <members>
        <user account_name="searchValue">
This XPath selects the user element.


Quote:
But I would think that this....
members/user[@account_name='asdf']
Would be in the members element.
Wrong, see above. You are selecting a user element because it's the rightmost thing in the XPath.

Quote:
It's the whole structure that I am not gettings and I can not seem to find any good web sites that go through it.
My first post linked you to the W3Schools Xpath tutorial. Wikipedia's XPath article is a good source too, and easier to navigate since it's only one page. The first google result for "XPath tutorial" is this really awesome site that lets you test XPath statements against the examlpes and highlights what's selected. Spend half a day reading these sites and an hour or two playing with XPath in some test documents; that's how I learned it. If you are willing to devote some time to gaining a basic knowledge of XPath, I'm certain it won't seem so hard anymore.

Quote:
So is this even close?
It's close. Let's explain each line as a sentence.

Code:
        m_xmld = New XmlDocument()
        m_xmld.Load("C:\Share\GR_Prd_DV1_roles.xml")
"Create a new XmlDocument based on the file."

        m_nodelist = m_xmld.SelectNodes("docuvault_settings/role_list/role")
"Select all role nodes and store them in m_nodelist."

        For Each m_node In m_nodelist
"Perform the following for every role node:"

            Dim RoleNode As XmlNode = m_node.SelectSingleNode("members/user[@account_name='" & Role_Search_Value_1.Text & "']")
    "Select a user node that is a child of this role node and has an account_name attribute
    " with the indicated value.  Store the user node in RoleNode."

            If RoleNode IsNot Nothing Then
    "If a user node with the indicated value was found:"

                Name = m_node.Attributes.GetNamedItem("obj_name").Value
        "Get the role node's obj_name attribute value and store it in the variable Name."

                m_xmld.SelectNodes("docuvault_settings/role_list/members")
        "Select all members elements in the document.  Throw the results away."
        
                Permission = m_node.Attributes.GetNamedItem("permission").Value
        "Get the value of the role node's permission attribute.  Store this value in the variable
        " Permission.  This will fail because the role node does not have this attribute.
For one, your variable names do not describe what you're working with, so it's easy to get confused.m_node is a role element. RoleNode is a user element. See how that might be confusing? The second problem is you are selecting the right elements but not accessing the right ones; if you want the permissions attribute from the user element, use the variable that represents the user element.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #31  
Old 08-14-2008, 08:16 AM
vb2008 vb2008 is offline
Regular
 
Join Date: Jan 2008
Posts: 88
Default

It really seems to me this would work...

Code:
  For Each m_node In m_nodelist

            Dim RoleNode As XmlNode = m_node.SelectSingleNode("members/user[@account_name='" & Role_Search_Value_1.Text & "']")

            If RoleNode IsNot Nothing Then

                Name = m_node.Attributes.GetNamedItem("obj_name").Value

                m_node.SelectSingleNode("members/user")
                Permission = m_node.Attributes.GetNamedItem("permission").Value
Reply With Quote
  #32  
Old 08-14-2008, 08:25 AM
AtmaWeapon's Avatar
AtmaWeaponXML reading more details AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

Explain why you believe it would work. I just laid out in excruciating detail why it doesn't work, and obviously it doesn't work because you wouldn't continue to ask if it was working. The scientific method involves creating a hypothesis and testing it; prove to me you are doing more than changing random lines and hoping they work. Put at least as much effort into explaining why it should work as I did into explaining why it won't work, and I can point out where things aren't working the way you think. If you continue to respond to my long explanations with short, simple, "I changed one line now is this it?" responses I'm afraid I'm wasting my time. You're going to have to learn something, then apply that knowledge to make at least two fundamental changes to your code.

My guess is you think this is what's happening:
Code:
m_node.SelectSingleNode("members/user")
Permission = m_node.Attributes.GetNamedItem("permission").Value
On the first line, you think you are changing m_node to refer to the user node; if this were true, then the next line would work. The documentation disagrees. SelectSingleNode returns the node that matches the XPath and does not change the node itself.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
  #33  
Old 08-14-2008, 08:49 AM
vb2008 vb2008 is offline
Regular
 
Join Date: Jan 2008
Posts: 88
Default

Sorry I posted that before I seen your last post :-) Looking at it now...
Reply With Quote
  #34  
Old 08-14-2008, 09:34 AM
vb2008 vb2008 is offline
Regular
 
Join Date: Jan 2008
Posts: 88
Default

Well I have looked at all the docs you listed and to be honest I am even more confused now. I guess XML is just not my thing. I won't bug you anymore as I can see your getting frustrated that I don't get it. Thanks for all the help though.
Reply With Quote
  #35  
Old 08-14-2008, 02:02 PM
vb2008 vb2008 is offline
Regular
 
Join Date: Jan 2008
Posts: 88
Default

well I went over to http://www.experts-exchange.com/ and asked the guys over there and this did the trick for anyone else who needs it...

Permission = RoleNode.Attributes.GetNamedItem("permission").InnerText
Reply With Quote
  #36  
Old 08-15-2008, 08:11 AM
AtmaWeapon's Avatar
AtmaWeaponXML reading more details AtmaWeapon is offline
Fabulous Florist

Forum Leader
* Guru *
 
Join Date: Feb 2004
Location: Austin, TX
Posts: 9,500
Default

I'm glad you found a solution, but I'd like to make a few suggestions that could make working with things easier. Also, I managed to think of an analogy that might help you relate to XPath better; it's one thing to have a working line of code and a completely different thing to understand what's going on. If you don't really understand the solution, you'll be stumped the next time you need this. I don't like to think you're a lost cause or a cargo cultist, so I'm going to make one last effort to teach you what's going on. So, let's discuss XPath, then I'll cover how I think your code should look.

Consider how paths work on your hard drive. Let's say you have a data drive with the drive letter D, and its contents look like this:
Code:
D
+ Text
| - file1.txt
| - file2.txt
|
+ Images
| + Vacation
| | - hotel1.jpg
| | - fun.jpg
In the notation used to designate file paths, you start with the drive letter. The drive letter is followed by a colon and it has to be the first thing you specify. Next comes the "path separator", a character that indicates the end of one path element and the beginning of another. So, to direct Windows to the root of your D drive, you can type this into Windows Explorer's address bar (we'll ignore the command prompt for reasons I'll keep to myself):
D:\

This tells Windows, "I want to be at the root of the D drive." What if you want to view the files in the Images directory? You start with the drive part, then add the name of the directory, then add another path separator:
D:\Images\

This tells Windows Explorer, "I want to view the item you reach by starting at the root of the D drive, then opening the Images directory." Windows Explorer figures out this is a directory and displays the files.

What if you want to view the file "file2.txt"? We start with the drive, add a path separator, add the Text directory, add a path separator, then add the file name:
D:\Text\file2.txt

Windows will interpet this as, "Start at the root of the D drive. Move to the 'Text' directory. From there, find the file 'file2.txt'."

The reason I bring this up is this is exactly how XPath works! Let's say we have this simple XML file:
Code:
<?xml version="1.0"?>
<AAA>
    <BBB />
    <BBB>
        <CCC>
            <DDD />
        </CCC>
    <BBB>
    <DDD />
</AAA>
Let's say you want to select the "AAA" node. You need to tell XPath how to get there. The instructions are, "Start at the root of the document and select any child elements named "AAA"." The XPath for this looks like:
AAA
The code to perform this query might look like:
Dim aaaNode As XmlNode = xDoc.SelectSingleNode("AAA")

Let's talk about how it's different from a file path. There's no drive; the node that you call one of the Select methods is considered the "root". There's no path separator here; the very last thing in an XPath query is what will be selected, so it's not valid to put a path separator on the end.

Another difference between XPath and file paths is you have the ability to say, "Get me anything that matches this". For example:
//DDD

This XPath statement starts with "//", which means "Find any child". So what we are saying is, "Find any child element named "DDD". xDoc.SelectNodes would return 2 nodes from this XPath, because there are 2 "DDD" elements in the document.

What if you only want the DDD element that's a child of CCC? You have many choices. One way is the same thing as wanting a file in a directory; the XPath would look like this:
AAA/BBB/CCC/DDD

This says, "I want only the DDD elements that are children of CCC elements; the CCC elements should be children of BBB elements; the BBB elements should be children of AAA elements; the AAA elements should be children of the root." See how it works like a file path?

Another option would be to look for all CCC nodes, then select any DDD nodes that are their children:
//CCC/DDD

This will select any CCC node in the document, then select any DDD nodes that are a child of CCC nodes.

Your other option here would be to first get the CCC element, then look for any DDD elements that are children. This is multiple steps:
Code:
Dim cccElement As XmlNode = xDoc.SelectSingleNode("AAA/BBB/CCC")
Dim dddElement As XmlNode = cccElement.SelectSingleNode("DDD")
Notice how in the 2nd XPath query we didn't need to say anything about AAA, BBB, or CCC. In this case, we are saying, "Starting at this CCC node, select any child nodes named DDD." We've changed the root of the XPath query.


Now, with the new knowledge, let's take a look at a program that executes your code as-is against the XML from post #20:
Code:
Imports System.Xml

Module Module1
    Private m_xmld As XmlDocument
    Private m_nodelist As XmlNodeList
    Private Name As String
    Private Permission As String
    Private searchString As String


    Sub Main()
        m_xmld = New XmlDocument()
        m_xmld.Load("test.xml")
        searchString = "afarner"

        m_nodelist = m_xmld.SelectNodes("docuvault_settings/role_list/role")

        For Each m_node As XmlNode In m_nodelist
            Dim RoleNode As XmlNode = m_node.SelectSingleNode("members/user[@account_name='" & searchString & "']")

            If RoleNode IsNot Nothing Then

                Name = m_node.Attributes.GetNamedItem("obj_name").Value

                m_xmld.SelectNodes("docuvault_settings/role_list/members")
                Permission = m_node.Attributes.GetNamedItem("permission").Value
            End If
        Next

        Console.WriteLine("Name: {0}, Permission: {1}", Name, Permission)
    End Sub

End Module
Line 16 is going to select all role elements because it says, "Start at the root of the document, then move to docuvault_settings elements; from there move to child nodes named role_list; from there move to child nodes named role. Select these role nodes." Then, we enter the For loop on line 18; for each role node we will do the following:

The user node that matches the search term will be stored in RoleNode. See why I'm complaining? It's an account, but you call it a role! The node is selected because you say, "Start at this role node, then select all child elements named members; select children of these nodes named user that have an account_name attribute with a value that matches some value. Return the first node that matches these criteria." So, what we end up with is all users in the current role that have the specific account_name attribute. We store this user in RoleNode.

Next, we verify that the user was found, and if it was, we store the value of the obj_name attribute of the current role (m_node) into Name. Line 25 is completely spurious. It says, "Start at the root of the document, then move to any child elements named docuvault_settings. From there, move to child elements named role_list. From there, move to child elements named members. Select all of these nodes." This returns every members element in the entire XML file. You don't need this for anything, and you don't do anything with it anyway so the results are just tossed aside.

Finally, you try to get the permission attribute from m_node. This is a role node, which does not have a permissions attribute, which is why it fails.

The people at experts-exchange told you to use a line of code that asks for the permissions attribute from RoleNode, which is the user element that matched your search. You were asking the wrong question.

Suggestions
GetNamedItem is redundant; you can access attributes by index. Use appropriate variable names. If you understood the concept of XPath, you'd still get tripped up by the variable names you are using.

Here's an improved version of your code that uses decent variable names; see if it doesn't look more clear once the variable names actually explain what they are holding:
Code:
        m_xmld = New XmlDocument()
        m_xmld.Load("test.xml")
        searchString = "afarner"

        allRoles = m_xmld.SelectNodes("docuvault_settings/role_list/role")

        For Each roleElement As XmlNode In allRoles
            Dim userElement As XmlNode = roleElement.SelectSingleNode("members/user[@account_name='" & searchString & "']")

            If userElement IsNot Nothing Then
                Name = roleElement.Attributes("obj_name").Value
                Permission = userElement.Attributes("permission").Value
            End If
        Next

        Console.WriteLine("Name: {0}, Permission: {1}", Name, Permission)
I urge you to strive to understand this content. Experts-exchange tends to just hand out answers, but if you rely on that rather than learning the concepts then I promise you somewhere down the line it's going to bite you.
__________________
.NET Resources
My FAQ threads | Tutor's Corner | Code Library
I would bet money 2/3 of .NET questions are already answered in one of these three places.
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
XML reading more details
XML reading more details
XML reading more details XML reading more details
XML reading more details
XML reading more details
XML reading more details XML reading more details XML reading more details XML reading more details XML reading more details XML reading more details XML reading more details
XML reading more details
XML reading more details
 
XML reading more details
XML reading more details
 
-->