|
Subject:
|
Parse XML doc using VB.NET into ASP.NET page
|
|
Posted By:
|
kwilliams
|
Post Date:
|
7/28/2005 10:04:07 AM
|
I'm new to XML and .NET, and this is what I'm wanting to do: I want a simple way to parse an XML doc using VB.NET syntax into an ASP.NET page using the ASP.NET Web Matrix, not Visual Studio.NET. I then want to declare all of the elements and nodes into variables, and use that data within the webpage.
Note: I do not intend to use ASP.NET's built-in web controls; I intend to use regular HTML controls for this task.
From what I've read so far, there are several methods for parsing XML data using VB.NET, including XMLTextReader, XMLDocument, and XMLTextWriter. Since I only want to display the elements & child nodes from the XML doc, I'm assuming that I need to use the XMLTextReader method. So far, every example that I've found is very complex and involves code for Visual Studio.NET, which I don't use. So I'm looking for a very simple solution that doesn't contain a bunch of mumbo-jumbo code that doesn't need to be there. I'd greatly appreciate any help on this subject, and I hope to hear from someone soon. Thanks.
So here's a snippet from my source XML doc: <ealerts> <alert> <title>eAlert - Title #1</title> <rss_url>#</rss_url><!-- URL to RSS feed --> <link>#</link><!-- Link to details page --> <image_url>http://SERVER/DIRECTORY/images/gif/ealert_title1.gif</image_url> <width>49</width> <height>48</height> <status>active</status><!-- "active" or "inactive" will show or hide ealert --> </alert> <alert> <title>eAlert - Title #2</title> <rss_url>#</rss_url><!-- URL to RSS feed --> <link>#</link><!-- Link to details page --> <image_url>http://SERVER/DIRECTORY/images/gif/ealert_title2.gif</image_url> <width>49</width> <height>48</height> <status>active</status><!-- "active" or "inactive" will show or hide ealert --> </alert> </ealerts>
...and here's how I'd like to display these "eAlerts" depending on the XML doc's data: <div id="topright"> <!--begin eAlerts--> <a href="#"><img title="eAlert - Title #1" height="48" alt="eAlert - Title #1" src="images/gif/ealert_title1.gif" width="49" /></a> <a href="#"><img title="eAlert - Title #2" height="48" alt="eAlert - Title #2" src="images/gif/ealert_title2.gif" width="49" /></a> <!--end eAlerts--> </div><!--end topright-->
KWilliams
|
|
Reply By:
|
Imar
|
Reply Date:
|
7/28/2005 10:24:51 AM
|
Hi there,
Is there any reason you don't want to use the built-in server controls? It feels a bit odd to use a technology, but not use its most important concepts. It's like buying a fast new car, but never switch into the second gear.
With those controls, things can be as easy as this:
First, add a DataGrid to your ASPX page:
<asp:DataGrid ID="Grid1" Runat="server" />
then in the Code Behind (or in the page itself) in Page_Load add something like this:Imports System.Data ' This goes at the top of the page, or with an @Import directive
Dim ds As DataSet = New DataSet
ds.ReadXml(Server.MapPath("XMLFile1.xml"))
Grid1.DataSource = ds
Grid1.DataBind()When you run this page, you get a plain grid with the records from the XML file.
You can customize the DataGrid with hyper link controls or whatever you see fit.
IMO, not choosing server controls is a big mistake, but maybe you have a good reason to do so??
Cheers,
Imar --------------------------------------- Imar Spaanjaars Everyone is unique, except for me.
|
|
Reply By:
|
kwilliams
|
Reply Date:
|
7/28/2005 10:39:03 AM
|
Hi Imar,
Thanks for the quick reply. To answer your question about why I don't want to use the ASP.NET built-in web controls, that's because I had nothing but trouble in figuring out how to use XML data within those controls for some time now. The biggest issue concerned how to access not only the main element from an XML file, but also all of its child nodes. Everytime I tried to use the method that you referred to, I'd get error messages whenever an XML doc contained more then one tier of child nodes. All I wanted to do was to pull all of the properties for each element into a set of variables, and then display that data. But unfortunately everytime I tried to get some advice on that subject from different forums, no one would reply.
Another BIG issue with the built-in web controls was their efficiency. Each page took forever to load, when regular VB.NET script referenced in a regular HTML control did not. Even if I was able to get the "Dataset" setup to work, this would always be a problem, as I want for my site to reasonably fast for almost all users.
So after a lot of frustration without success, I decided that it would likely be best to use the XMLTextReader and XMLDocument methods through a VB.NET script, and then apply those variables to different sections of the page without the use of web controls.
If you know of a solution to my problems with the ASP.NET web control's efficiency, problems with pulling in XML data, please let me know. And maybe then I'd reconsider my current position. Thanks again for your response, as it's greatly appreciated.
KWilliams
|
|
Reply By:
|
Imar
|
Reply Date:
|
7/28/2005 11:15:19 AM
|
If you want to read an XML document line by line, you may want to look in to the XPathNavigator class: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfSystemXmlXPathXPathNavigatorClassTopic.asp
This allows you to walk a document, selecting elements and attributes that match your criteria.
But did you try out my code? Does that work for you? It runs just as fast as any other page here. With a few nested controls (e.g HyperLink controls) you can quickly establish what you need....
Cheers,
Imar --------------------------------------- Imar Spaanjaars Everyone is unique, except for me.
|
|
Reply By:
|
kwilliams
|
Reply Date:
|
7/28/2005 11:21:11 AM
|
I did try your code, but it gave me the same error as I always get. It doesn't recognize any child nodes from the source XML file; only the first tier element. So that can't help me if I have an XML doc with more than one tier of nodes.
I'll check out your referenced article and other info on the XPathNavigator class, and hopefully that will be what I need. But I'm finding this entire process of simply trying to access an XML document and display all of that doc's nodes to be rather daunting. I thought that the whole process would be simpler than this. But thanks again for the info.
KWilliams
|
|
Reply By:
|
Imar
|
Reply Date:
|
7/28/2005 11:32:02 AM
|
What error do you get exactly? Can you post it here?
Instead of this:
Grid1.DataSource = ds
try this:
Grid1.DataSource = ds.Tables(0).DefaultView
That should work and show you a two dimensional table with the XML you posted here. I get two records each with 7 columns. Isn't that what you're trying to accomplish??
Imar --------------------------------------- Imar Spaanjaars Everyone is unique, except for me.
|
|
Reply By:
|
kwilliams
|
Reply Date:
|
7/28/2005 11:56:59 AM
|
The example XML doc that I posted intentionally only contained 1 tier of data because I wanted to keep it simple for my original request. But if I try to use that method for an XML doc like this: <ROOT> <ELEMENT> <CHILDNODE1>... <CHILDNODE2>...</CHILDNODE2> </CHILDNODE1> </ELEMENT> </ROOT>
The "ROOT", "ELEMENT", and "CHILDNODE1" data will display fine. But attempting to place "CHILDNODE2" inslide of a web control results in this error message: Server Error in '/' Application. CHILDNODE2 is neither a DataColumn nor a DataRelation for table ROOT. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.ArgumentException: CHILDNODE2 is neither a DataColumn nor a DataRelation for table ROOT.
In the meantime, I'll try your suggestion of trying this: Grid1.DataSource = ds.Tables(0).DefaultView
...instead of this: Grid1.DataSource = ds
KWilliams
|
|
Reply By:
|
Imar
|
Reply Date:
|
7/28/2005 12:39:47 PM
|
quote: Originally posted by kwilliams The example XML doc that I posted intentionally only contained 1 tier of data because I wanted to keep it simple for my original request.
Right, that isn't really helpful and caused a lot of confusion ;-)
Anyway, you say you have "code for Visual Basic .NET" and you don't use that. However, the same code should run fine in Web Matrix or even in pages created in Notepad. Would it help if you posted that code here?
Otherwise, I think you need to load the document into an XmlDocument and then use its properties like ChildNodes or FirstChild to get the nodes you do want to work with. Take a look here: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemxmlxmldocumentmemberstopic.asp
I don't use Xml in these kind of scenarios much, so I don't have any ready made examples here. I am sure that Google should bring up loads of useful stuff though...
Cheers,
Imar --------------------------------------- Imar Spaanjaars Everyone is unique, except for me.
|
|
Reply By:
|
kwilliams
|
Reply Date:
|
7/28/2005 1:21:21 PM
|
quote: Originally posted by kwilliams The example XML doc that I posted intentionally only contained 1 tier of data because I wanted to keep it simple for my original request.
quote: Reply posted by ImarRight, that isn't really helpful and caused a lot of confusion ;-)
What I was meaning is that I only wanted to get the code that would use one of the XML parse methods to extract data from an XML file. My original post wasn't concerning how to use ASP.NET's web controls, because of the problems I ran into in the past.
quote: Anyway, you say you have "code for Visual Basic .NET" and you don't use that. However, the same code should run fine in Web Matrix or even in pages created in Notepad.
That was what I was originally asking for...VB.NET code that uses the XMLTextReader or XMLDocument parsing method to pull in XML data, and then assign that data to variables. My problem with the referenced sites (like http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemxmlxmldocumentclassctortopic1.asp) is that they are intended for developers who use VisualStudio.NET and all of its built-in functions. I simply wanted to see if there was a way to accomplish this task in a much simpler fashion, without all of the properties meant for VisualStudio.NET developers.
quote: Would it help if you posted that code here?
Sure.
quote: Otherwise, I think you need to load the document into an XmlDocument and then use its properties like ChildNodes or FirstChild to get the nodes you do want to work with. Take a look here: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemxmlxmldocumentmemberstopic.asp
This is basically what I'm looking for, without all of the extra stuff meant for a VisualStudio.NET environment.
It's really too bad that almost all examples using VB.NET assume that you use VisualStudio.NET. Personally, I don't need VisualStudio.NET, as it's like a hammer when I need a needle. I'm not exactly sure why Microsoft developed the Web Matrix when they don't give enough examples of how to do complex tasks within their own program. But I guess...that's Microsoft.
quote: I don't use Xml in these kind of scenarios much, so I don't have any ready made examples here. I am sure that Google should bring up loads of useful stuff though...
Well, I've appreciated your quick and thorough advice, and I'll make sure to check Google's resources out also. Thanks again Imar:)
KWilliams
|
|
Reply By:
|
Imar
|
Reply Date:
|
7/28/2005 1:32:32 PM
|
I am not sure I understand the problem with code for Visual Studio. What's there in this page: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemxmlxmldocumentclassctortopic1.asp that requires Visual Studio??
All you need to do is move the Imports statement to an Import directive, and then you can use all of the code directly. Obviously, Console.WriteLine is for a console app so you need something like Response.Write or, better, myLabel.Text = but other than that, that code works fine in the Web Matrix.
But maybe I am overlooking something??
Imar --------------------------------------- Imar Spaanjaars Everyone is unique, except for me.
|
|
Reply By:
|
kwilliams
|
Reply Date:
|
7/28/2005 2:42:00 PM
|
Ok, well this is what I've got.
XML doc: <ealerts> <alert> <title>eAlert - Title #1</title> <rss_url>#</rss_url><!-- URL to RSS feed --> <link>#</link><!-- Link to details page --> <image_url>http://SERVER/DIRECTORY/images/gif/ealert_title1.gif</image_url> <width>49</width> <height>48</height> <status>active</status><!-- "active" or "inactive" will show or hide ealert --> </alert> <alert> <title>eAlert - Title #2</title> <rss_url>#</rss_url><!-- URL to RSS feed --> <link>#</link><!-- Link to details page --> <image_url>http://SERVER/DIRECTORY/images/gif/ealert_title2.gif</image_url> <width>49</width> <height>48</height> <status>active</status><!-- "active" or "inactive" will show or hide ealert --> </alert> <!--...AND SO ON...--> </ealerts> XMLDocument method:
<%@ Page Language="VB" ContentType="text/html" ResponseEncoding="iso-8859-1" Debug="true" %>
<%@ Import Namespace="System" %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.Xml" %>
<script runat="server">
'Pull in eAlerts data
Sub Main()
Dim m_xmld As XmlDocument
Dim m_nodelist As XmlNodeList
Dim m_node As XmlNode
'Create the XML Document
m_xmld = New XmlDocument()
'Load the Xml file
m_xmld.Load("http://SERVER/DIRECTORY/docs/xml/ealerts.xml")
'Get the list of name nodes
m_nodelist = m_xmld.SelectNodes("/ealerts/alert")
'Loop through the nodes
For Each m_node In m_nodelist
Dim titleValue = m_node.ChildNodes.Item(0).InnerText
Dim rss_urlValue = m_node.ChildNodes.Item(1).InnerText
Dim linkValue = m_node.ChildNodes.Item(2).InnerText
Dim image_urlValue = m_node.ChildNodes.Item(3).InnerText
Dim widthValue = m_node.ChildNodes.Item(4).InnerText
Dim heightValue = m_node.ChildNodes.Item(5).InnerText
Dim statusValue = m_node.ChildNodes.Item(6).InnerText
'Get the Gender Attribute Value
'Dim genderAttribute = m_node.Attributes.GetNamedItem("gender").Value
'Write Result to the Console
Response.Write("<strong>eAlert</strong><br />Title: " & titleValue & _
" RSS URL: " & rss_urlValue & _
" Link: " & linkValue & _
" Image URL: " & image_urlValue & _
" Width: " & widthValue & _
" Height: " & heightValue & _
" Status: " & statusValue)
Next
End Sub
</script>
The good news is that no errors are returned, but the bad news is neither are any results...just a blank page. I'm not sure why that is, because the properties & syntax appear to be correct. If you see anything that I'm obviously missing, please let me know. I'll just keep on testing it out in the meantime.
KWilliams
|
|
Reply By:
|
Imar
|
Reply Date:
|
7/28/2005 2:51:32 PM
|
Are you sure that http://SERVER/DIRECTORY/docs/xml/ealerts.xml results in a valid document that your web server is allowed to read?
Your code runs fine on my machine....
Cheers,
Imar --------------------------------------- Imar Spaanjaars Everyone is unique, except for me. While typing this post, I was listening to: Mosquito Song by Queens of the Stone Age (Track 15 from the album: Songs For The Deaf) What's This?
|
|
Reply By:
|
kwilliams
|
Reply Date:
|
7/28/2005 3:12:40 PM
|
It should, but since I'm doing all of this on an internal test-server, that could be possible. I'll check with my Network Administrator tomorrow morning about making sure that I have Read writes to that directory. But I'm not sure why I wouldn't, as I've been testing other things on that directory that requires read & write access with success.
Thanks for testing it out on your machine. That helps me to know that it could be a problem with the security vs. the code.
KWilliams
|
|
Reply By:
|
kwilliams
|
Reply Date:
|
7/28/2005 3:50:23 PM
|
Would you mind telling me exactly how you tested the code out that I included with my previous post? I even tried creating a copy of the XML file into the same directory as the ASPX file with no success. I just can't figure out why it's working for you and not for me. How frustrating...
KWilliams
|
|
Reply By:
|
Imar
|
Reply Date:
|
7/28/2005 4:02:26 PM
|
I must admit I cheated a bit by moving this code into a Visual Studio Project with a code behind file. This may lead you to believe that this code does only work with Visual Studio, but I ensure you that's not the case.
The one thing that I changed, apart from moving the @Import to Imports statements in my code behind file, was drop the Main method and instead dump your code in the Page_Load of my page.
That is also probably causing this code not to run on your machine. In the ASP.NET world, Main is not a magical name for a method. Instead of Main you could have used Imar() or KWilliams() or whatever. So, basically, the framework treats this as a normal method and waits for code that triggers it.
To run the code when the page loads, you need to add it to the Page_Load method. In Visual Studio .NET you can declare that method like this:
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' Code here
End Sub
However, in the Web Matrix, I think the AutoEventWireUp or whatever it is called is on by default, so you may get away with just Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)
So, move your code to a method that is called at run-time and see if that makes a difference....
Cheers,
Imar --------------------------------------- Imar Spaanjaars Everyone is unique, except for me. While typing this post, I was listening to: 06 - Monsters In The Parasol by Queens of the Stone Age (Track 6 from the album: Rated R) What's This?
|
|
Reply By:
|
kwilliams
|
Reply Date:
|
7/28/2005 4:10:36 PM
|
Hallelujah...it worked. Here's my final code:
<%@ Page Language="VB" ContentType="text/html" ResponseEncoding="iso-8859-1" Debug="true" %>
<%@ import Namespace="System" %>
<%@ import Namespace="System.IO" %>
<%@ import Namespace="System.Xml" %>
<script runat="server">
'Pull in eAlerts data
Sub Page_Load
If Not Page.IsPostBack then
Dim m_xmld As XmlDocument
Dim m_nodelist As XmlNodeList
Dim m_node As XmlNode
'Create the XML Document
m_xmld = New XmlDocument()
'Load the Xml file
m_xmld.Load("http://SERVER/DIRECTORY/docs/xml/ealerts.xml")
'Get the list of name nodes
m_nodelist = m_xmld.SelectNodes("/ealerts/alert")
'Loop through the nodes
For Each m_node In m_nodelist
Dim titleValue = m_node.ChildNodes.Item(0).InnerText
Dim rss_urlValue = m_node.ChildNodes.Item(1).InnerText
Dim linkValue = m_node.ChildNodes.Item(2).InnerText
Dim image_urlValue = m_node.ChildNodes.Item(3).InnerText
Dim widthValue = m_node.ChildNodes.Item(4).InnerText
Dim heightValue = m_node.ChildNodes.Item(5).InnerText
Dim statusValue = m_node.ChildNodes.Item(6).InnerText
'Get the Gender Attribute Value
'Dim genderAttribute = m_node.Attributes.GetNamedItem("gender").Value
'Write Result to the Console
Response.Write("<strong>eAlert</strong><br />" & _
"Title: " & titleValue & _
" RSS URL: " & rss_urlValue & _
" Link: " & linkValue & _
" Image URL: " & image_urlValue & _
" Width: " & widthValue & _
" Height: " & heightValue & _
" Status: " & statusValue)
Next
End If
End Sub
</script>
...and it works like a charm. Thanks SO MUCH for your patient, thorough, and clearly wonderful help. You've been a great resource during this frustrating process, and I REALLY appreciate it. This forum is VERY lucky to have you as a member, and I'm not just saying that:)
KWilliams
|
|
Reply By:
|
Imar
|
Reply Date:
|
7/28/2005 4:16:30 PM
|
You're welcome. Glad it's all working now.
Cheers,
Imar --------------------------------------- Imar Spaanjaars Everyone is unique, except for me. While typing this post, I was listening to: Government Flu by Dead Kennedys (Track 1 from the album: Plastic Surgery Disasters + In God We Trust) What's This?
|
|
Reply By:
|
vkpatil
|
Reply Date:
|
11/11/2005 9:42:50 AM
|
err.... can we use XSLT instead of loading of XMLDocument and then walking thru the document tree? with XSLT i guess you don't have to do much coding and then if you change your mind to display the content in different format you can always go back to the xsl file and change it right?
<Programerror>Vijay.Patil</Programerror>
|