-

My Blog

My thoughts on it all

Newbie Question VB.net and XML

Nov 6, 2003 — Hello all!

I am a friend of Aesopian and dcormier. I am currently taking VB.net II at the spc clw campus. We just finished working with SQL and OLEDB and such for our projects. I had a bit of a hard time getting SQL to run on my machine but it works now. I am running XP home ed.

So here is my question, actually I have two...
1) When I am using Visual Studio 2003, I can browse my server explorer and see the SQL server and the four "databases" that come with it, but are totally blank. How do I create databases that I can use and view from that list? (this is where our instructor had use create data adapters from and, of course, connections to the datasource)


2) I want to access an XML file that has data already in the elements and use the file like a pseudo-database. I read the help that microsoft provided and this is what I have so far.
[quote]
Dim dsChars1XML As New DataSet("xmlsheet")

Private Sub btnRead_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRead.Click

Dim filePath As String
filePath = "C:\xmltemp\xmldatabase.xml"
dsChars1XML.ReadXml(filePath)
With dgrStuff
.DataSource = dsChars1XML
.DataMember = "mySheet"
.CaptionText = .DataMember
End Sub
[/quote]

So that displays the first table in the XML database I have, And it gives me the data that is in the respective elements of that table.

Now how do I go about getting just one piece of information(not a whole table, just one of the elements) and displaying it in a textbox or label.

If someone knows how to create a connection to the XML file and then a data adapter, then I would know how to do the rest. But since everything I have tried in the server explorer doesn't allow me to connect to and XML file... I am stumped.

DataBind() says:

Well, first of all, if you want to create a new database in the server explorer, you don't need a data adapter or any kind of data provider -- just right-click the SQL server you want to add to and select "Add new database."

As to iterating through nodes in your XML file, your best bet probably is to learn about XPath and select the proper XPath in your XMLDoc and then derive a NodeList from this. You can then just iterate through each node in the node list.

Something like (someone correct my VB syntax if it's incorrect)....
[b]
Dim cXmlDocument as XmlDocument = new XmlDocument()
cXmlDocument.Load("foo.xml")
'whatever XPath you want
strExpr = String.Format("//{0}:item", "yournamespace")
Dim cNsManager as XmlNamespaceManager = new XmlNamespaceManager(cXmlDocument.NameTable)
Dim cNodelist as XmlNodeList = cXmlDocument.SelectNodes(strExpr, cNsManager)
Dim cXmlNode as XmlNode
for each cXmlNode in cNodelist
'Something to do here
next
[/b]

You can then select the XML of the node of the innertext or whatever is it you want.

Why don't you post an XML snippet so we know what you are dealing with?

You wouldn't need a DataAdapter for your XML file (but you COULD put your XML into a DataSet if you wanted). If you want to do this, you would simply populate a DataSet with the [i]ReadXml[/i] method of the DataSet. However, keep in mind that the DataSet has quite a fair amount of overhead associated with it, much more than a NodeList.

Also, if you are just getting one-way data from SQL a DataReader would be much better anyway (than a DataAdapter/DataSet which has a much higher cost).

[edit]Edited by DataBind(): Nov. 6, 2003 - 2:01:34 PM[/edit]

wtbn2002 says:

Thanks for the reply, It was helpful.

I created a new database like you instructed. I will play around with that later...

Well I looked up Xpath, and this is the link I found informative.

http://msdn.microsoft.com/msdnmag/issues/01/01/xml/default.aspx

There is a lot of information there, and I am still reading and digesting it. I think most of the code snippets are written in C#. So that is taking some getting used too since I only know the VB.net stuff.

I actually plan on writing information back to the XML. So I could start with a blank XML file and write to it, or edit a current one, etc...

So do I need to fill a (sorry error here) Dataview with a dataset with the readxml method?

How do I do that?

[edit]Edited by wtbn2002: Nov. 6, 2003 - 8:46:26 PM[/edit]

DataBind() says:

If you have made up your mind that you want to fill a DataSet with your XmlStream, then the first thing you are going to have to do is to learn about the XmlReadMode argument of the ReadXml method of the DataSet class. Otherwise when you read the XmlStream or XmlDoc into the DataSet you are going to get a very strange DataSet schema which will probably not be what you are expecting.

But if you don't care about the DataSet schema, then it is as simple as:

[b]Dim myDS As DataSet = New DataSet
myDS.ReadXml("input.xml", [XmlReadMode])
[/b]

This will get you the DataSet object populated and you can just grab a defaultView from the Tables collection of your DataSet.

BTW, a GREAT book on this subject is Microsoft's ADO.NET Step by Step. Can't recommend it enough.

HTH

wtbn2002 says:

Actually I do care about the schema... I think. I want to be able to retrieve the values in each element. Then display just one value in a textbox. So I need to know how to get to the values.

I did get the enitre XML loaded in a datagrid. And I was able to click through the whole thing and see all the data. That was cool.

But now I want to get to just the values... Maybe I don't need to assign them to textboxes. If there is a way to get the XML file to display in a form like it would on a web page and, you can click buttons to change the individual values and display those changes. That is where I am going with this.

DataBind() says:

Let me see if I understand what you want.

You want a form populated with data from XML which the user can submit which will update the XML?

I still think you are better off using a NodeList that you can simply iterate through and assign the value of each node to a TextBox in the CodeBehind. Much simpler, really.

However, if you still want to use a DataSet, you can simply databind your datagrid with the defaultview of the basic table within the DataSet (Something like DataSet.Tables(0).DefaultView) unless you have more than one table.

If you use a datagrid, you can control the columns collection through the control's properties and add a button grid. VS 2003 has a button-column you can add that will create a "Select, edit, cancel" link to each row which you can then handle via those events.

Or you can use a datarepeater which will give you MUCH more control over how you want to render the data -- you can add a textbox and a button, or whatever.

OR if you know the format and length will be constant, just hardcode the servercontrols (or add them to the controls collection dynamically -- now THAT would be sexy.)

Here is an example of how to use the nodelist:

(psuedo-code)
[b]
XmlDocument xd = new XmlDOcument
xd.LoadXml("foo.xml")
XmlNamespaceManager xnm = new XmlNamespaceManager
//I dont know if you have an XML namespace or not
xnm.AddNamespace("namespacename", "xml namespace name in Doc")
//Select your nodelist here with an XPath -- MSDN has a great reference on how to build
// an XPath
XmlNodeList xnl = xd.SelectNodes("/bd:RootElementName/bd:/node()",xnm)
/* Now that you have a NodeList, you could be really Sexy and insert it into a DataSet if you wanted to. */
//Create DataTable
DataTable dtBaseData = new DataTable()
DataRow drBaseData
dtBaseData.Columns.Add
(new DataColumn("Column Name1",
System.Type.GetType("System.String", true)))
dtBaseData.Columns.Add
(new DataColumn("Column Name2",
System.Type.GetType("System.String", true)))
//iterate through XML and add values to DataTable
IEnumerator ienum = xnl.GetEnumerator()
while (ienum.MoveNext())
{
XmlNode xNode = (XmlNode) ienum.Current
if(xNode.Name == "NodeyouWant")
{
drBaseData[0] = xNode.InnerText
}
if(xNode.Name == "OtherNOdeYouWant")
{
drBaseData[1] = xNode.InnerText
}
dtBaseData.Rows.Add(drBaseData);
}
dvSubscription = new DataView(dtBaseData)
DataGrid.DataSource = dvSubscription
DataGrid.DataBind() //HEY! That's MY name
dvSubscription.Dispose() //ALWAYS dispose unmanaged resources
[/b]
This code is rough -- it won't compile.

Or, you could simply do this during the iteration stage:
[b]
while (ienum.MoveNext())
{
XmlNode xNode = (XmlNode) ienum.Current
if(xNode.Name == "NodeyouWant")
{
TextBoxA.Text = xNode.InnerText
}
if(xNode.Name == "NodeyouWant2")
{
TextBoxB.Text = xNode.InnerText
}
}
[/b]

Or, you could write to the node rather than read during the iteration -- maybe on PostBack to record changes?

Does this help? I would be more than willing to break it down mroe if you need, I'm not really sure how familiar you are with the technology. Also, I posted most of the code in psuedo-C#, not VB. But it's really just the objects that you need, anyway.

HTH!

[edit]Edited by DataBind(): Nov. 7, 2003 - 7:49:10 PM[/edit]

vampirical says:

[quote]you can simply databind your datagrid[/quote]
Ah, DataBind() talking about databind.
[quote]DataGrid.DataBind() //HEY! That's MY name[/quote]

All that VB was getting hard to read but that pseudo-C# makes it all better ;)

I'd be interested to see the implementation of this wtbn2002, looks interesting.

DataBind() says:

The MSDN online [link http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk/htm/sdk_intro_6g53.asp]MSXML SDK[/link] has GREAT [link http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk/htm/xpath_ref_overview_0pph.asp]references on XPath.[/link]

[link http://msdn.microsoft.com/library/default.asp?url=/library/en-us/xmlsdk/htm/xpath_syntax2_3prn.asp]This has some exampls on using an XPath to select the nodes you want[/link]

wtbn2002 says:

I think that last bit of code will be helpful. I have to read up more about Xpath and talk with Aesopian about it a bit. Then I think I will have a better idea of what I need to do to get the values in the elements. I can tell that I am close now. Just a little study and trial and error and I will have it.

I am basically writting a program that computerizes a teadious task that is normally done on paper.

The jist of it is this: I spend 3 hours looking up values from a reference, and plugging them into places on a form. This form is about 4 pages long. Once certain values are established, you can look them up in the reference and plug in the values on the form.

If I put the reference in a database. And then I setup the form in an XML format. I accomplish two things:
1) I make it so that I can fill out the forms faster, and I can view them from a webpage.
2) I can then take forms from the webpage and change any of the values when they need to be changed and update them.

And lastly I will be able to print exactly what I see so that the forms we are all used to do not change.

So ultimately, I want to be using the program to make things faster. I want to use comboBoxes to select core values and then have the program automatically fill in the blanks relating to that value.

Here is where things really get tricky, There is more than one reference that we use. So what data I need to reference depends on some of the initial values.

That give you a good idea of what I am doing and why I want to use XML in conjunction with databases?

P.S. Thanks for all your help thus far. I really appreciate it.

P.P.S. As an added "sexy" thing, I wonder if there is a way to see the finished form in all its XML glory before finishing the program. That way I wouldn't have to save the file and then go browse it and then come back and edit it and then go browse it... I could just do it all in the program.

DataBind() says:

I don't really understand why you are using XML [i]and[/i] SQL -- it seems like an extra level of abstraction that isn't really needed.

But yes, you could easily control wether the data was "written" or not during the postback event -- on PostBack, just check to see if boolWrite is set to true of not.

in other words, like this (during PageLoad):

if(!IsPostBack)
bWrite = false;
if(IsPostBack)
if(bWrite = false) then displayonly()
else
writetoDB()

And when it is displayed only, when you click the confirm button, change bWrite to true.

Or something like that.

Let me know if you need any more help.

Hope it all works out!

vampirical says:

I'm a bit confused as to why all this effort is needed to achieve that end result. If I wanted to do something similar I'd either simply skip the XML and just code a front end for the database(s) or if I was going to use XML for whatever reason I would skip the database, just have a front end that works with a number of XML documents.

But then again I've never seen the need for ever using XML and databases this closely together.

DataBind() says:

I guess if you wanted to drive the layout of your form from XML that would make sense -- so you could change how many textboxes and stuff were rendered by changing the xml. That is a really good use of XML -- and THAT would be sexy.

DataBind() says:

Another shortcut is this:

if you have XML and the XML is like this:

<states>

<state name=Arizona id=1/>

<state name=Washington id=2/>

</states>

then you can just do this:

DataSet ds = new DataSet();
ds.ReadXml("c:\\foo.xml");
DataView dv = new DataView(ds.Tables["state"]);

vampirical says:

If that does what It appears to, then THAT is sexy.

All of this is making me consider actually working on that bug submission board I dreamed up before, it could be so nice.

Hmm...maybe after this essay is due.

Post A Reply:





Sorry, but before you can reply you must either log in or sign up.