|
-
Aug 18th, 2010, 10:17 AM
#1
Parsing an XML file
Hi Guys,
I'm wanting to have the option in my app to save configuration settings and then be able to import them on another machine or when the application is launched later. So I've got my saving routine working fine, using the XmlWriter class to write various settings to the XML file. I'm not quite sure what I should be using to do the parsing of the XML file to read the settings back in though, as there seems to be a few different ways to do this.
Should I be creating an XmlDocument instance from the XML file and then using the ReadNode method or one of the other similar methods? Or should I be using the XmlReader class and one of its methods?
If it makes any difference, this is the format of my XML file:
Code:
<?xml version="1.0" encoding="utf-8" ?>
<!-- MY_APP_NAME Saved Settings - Version 0.9.5.0 -->
<SearchSettings>
<Setting1>Some string here</Setting1>
<Setting2 />
<Setting3>true</Setting3>
<Setting4 />
<Setting5 />
<Setting6>false</Setting6>
</SearchSettings>
Cheers
Chris
-
Aug 18th, 2010, 10:30 AM
#2
Re: Parsing an XML file
I find it much easier to use XElement and axis properties to read XML files compared to using XmlDocument.
Code:
Dim xml = XElement.Load("c:\Settings.xml")
Dim setting1 = xml...<Setting1>.Value
MsgBox(setting1)
-
Aug 18th, 2010, 11:21 AM
#3
Re: Parsing an XML file
There's no one "right" answer to this question, but I can outline the answers and let you pick one 
There's two categories of XML parsers I'm aware of, I call them DOM and SAX parsers.
SAX parsers are named based on one of the first parsers to use this technique. It's more like how you read a text file line by line, only a SAX parser reads node by node. .NET's version of this kind of parser is the XmlReader, and it's kind of strange compared to the traditional implementation. In the traditional implementations, you call some kind of Read() method that reads a node, then the parser raises an event that represents what kind of node was read. For example, the first few events raised in your example document might be DocumentRoot, Comment, StartElement, StartElement. .NET's parser doesn't raise the events, instead you use properties and methods to determine what node you're on and extract data. To get the value of the Setting1 element, you'd have to write code like this:
Code:
Dim reader As XmlReader = XmlReader.Create("test.xml")
Dim setting1 As String
While reader.Read()
If reader.NodeType = XmlNodeType.Element Then
If reader.Name = "Setting1" Then
setting1 = reader.ReadElementContentAsString()
End If
End If
End While
DOM parsers read the entire XML file and form a document model in memory. This allows you to use a special language called XPath to query the file for information quickly. XPath is too big to discuss in this answer, but tutorials exist. The workflow for a DOM parser is much different; you load the file, then make queries. Here's the code that would fetch the value of the Setting1 element:
Code:
Dim setting1 As String
Dim doc As New XmlDocument
doc.Load("test.xml")
Dim setting1Node As XmlNode = doc.SelectSingleNode("//Setting1")
setting1 = setting1Node.InnerText
Joacim Andersson is pointing you to XElement, which is related to a different DOM parser that was introduced in (I think) VS 2008. It comes with a neat inline syntax for working with the DOM in VB .NET. You'll have to lean on him for more explanation; I work mostly in C# and thus I'm more familiar with XmlDocument and XmlReader.
Why are there so many choices? Each has tradeoffs.
DOM parsers obviously require less code and make it easier to get to a particular element in a file. DOM parsers can read anything in the file at any time; SAX parsers can only read one-way so if you need to get something from earlier in the file you have to start over from the beginning. SAX parsers read one element at a time and thus use very little memory; DOM parsers must hold the entire DOM in memory. XPath lets you do some neat queries against the file, so it can be easier to pull weirdo stuff from random places.
So for small files or files that require some kind of complicated querying, I usually use the DOM parser XmlDocument. If I start to notice the load time, I have to switch to a SAX parser, and I usually end up building a data structure that simulates what I'd be doing with the DOM parser anyway. I can't tell you what'd be best for your solution, but I have a hunch based on your example that one of the DOM parsers will be fine. For redundancy, don't assume since I didn't talk about XElement I disagree with Joacim Andersson's post; I don't have enough experience with XElement to have an opinion on that technique.
-
Aug 18th, 2010, 11:36 AM
#4
Re: Parsing an XML file
XElement works in C# as well, but C# does not have XML literals and axis properties which makes XML so easy to use in VB. Here is a very basic example on how you can use XML literals to create an XML file.
Code:
Dim xml = <SearchSettings>
<Setting1><%= TextBox1.Text %></Setting1>
</SearchSettings>
xml.Save("c:\Settings.xml")
-
Aug 18th, 2010, 02:11 PM
#5
Re: Parsing an XML file
Thanks to both of you - I'll have a play around with each of the methods but it seems like the XmlDocument is going to be the best way for me to do what I want
Also, I never knew you could use XML literals in VB like that so thanks for that handy tip as well
-
Aug 18th, 2010, 02:18 PM
#6
Re: Parsing an XML file
I know it's really a great standard, but consider not using XML as it's much easier to parse, takes up less space, and is faster. You could even rely on order:
Code:
MY_APP_NAME 0.9.5.0
Some string here
true
false
Last edited by minitech; Aug 18th, 2010 at 02:21 PM.
-
Aug 18th, 2010, 02:50 PM
#7
Re: Parsing an XML file
Trouble with that is its very easy for a value to end up in the wrong place then...
I guess if I really wanted to I could just have each line start with the name of the setting (like in an INF file), but to be honest as its only a handful of settings and it wont be something that is commonly done then I'm not too bothered about performance - I'd rather go for robustness
-
Aug 18th, 2010, 03:01 PM
#8
Re: Parsing an XML file
Well, if you don't have many settings, consider that it's much easier to implement.
-
Aug 18th, 2010, 03:27 PM
#9
Re: Parsing an XML file
 Originally Posted by chris128
Thanks to both of you - I'll have a play around with each of the methods but it seems like the XmlDocument is going to be the best way for me to do what I want 
How can you consider that the XmlDocument be easier to use than axis properties as I showed in post #2? And yes, you actually use 3 dots in: xml...<whatever>.Value
Last edited by Joacim Andersson; Aug 18th, 2010 at 03:30 PM.
-
Aug 18th, 2010, 03:57 PM
#10
Re: Parsing an XML file
I dont know I just prefer and understand that method more - plus there is a chance that this project might need to target .NET 2.0 so I am trying to avoid anything that is new in 3/3.5 like LINQ (I believe the code you posted uses LINQ but correct me if I'm wrong).
Anyway, its not like there is much difference between them... this is yours:
Code:
Dim xml = XElement.Load("c:\Settings.xml")
Dim setting1 = xml...<Setting1>.Value
and this is what I'm doing:
Code:
Dim XmlDoc As New Xml.XmlDocument
XmlDoc.Load(XmlLocation)
Dim Setting1 As String = XmlDoc.SelectSingleNode("//Setting1").InnerText
I just prefer that as I can understand it... I'm not a fan of LINQ if I'm honest but that is probably just because I have never really spent time to learn it. Oh and it didnt help that I couldn't even find the XElement class lol MSDN says its in System.Xml.Linq but that namespace doesn't appear in intellisense for me and I'm not willing to add another reference to my project (if that is what is required) just for this.
-
Aug 18th, 2010, 04:04 PM
#11
Re: Parsing an XML file
Oh and I've got another question about this actually what is the best way to check for the XML node not existing? Like if my Settings1 node didnt exist, I would like to tell the user which node it is that is missing. I figure I would just need to try and get each node and then check to see if the object returned is Nothing but just wondering if there is any other better way?
Alternatively I could wrap each attempt to read a node in a Try/Catch that just catches NullReference exceptions, as that will be thrown when I attempt to get the InnerText property of a node that doesnt exist. I dont like this option at all but just thought I would mention that I had considered it... very briefly.
-
Aug 18th, 2010, 08:31 PM
#12
Re: Parsing an XML file
Nope, my code has nothing to do with LINQ, but you are correct that XElement was introduced in .Net 3.5. But your original post did not state that you wanted to read an XML file in framework 2.0. Personally I've left the XmlDocument behind me since I only do new development in 3.5 or 4.0
-
Aug 18th, 2010, 09:46 PM
#13
Re: Parsing an XML file
Performing a query, then seeing the result is Nothing is the only way I can think of to verify that a particular element doesn't exist. In the XmlReader the only thing you can do is parse the whole file then note that the element was never found. I'd assume XElement returns Nothing like XmlDocument.
-
Aug 19th, 2010, 03:02 AM
#14
Re: Parsing an XML file
 Originally Posted by Joacim Andersson
Nope, my code has nothing to do with LINQ, but you are correct that XElement was introduced in .Net 3.5. But your original post did not state that you wanted to read an XML file in framework 2.0. Personally I've left the XmlDocument behind me since I only do new development in 3.5 or 4.0
I'm surprised it has nothing to do with LINQ when it is in an assembly that has LINQ in the name 
Performing a query, then seeing the result is Nothing is the only way I can think of to verify that a particular element doesn't exist.
OK cool thanks, as long as I'm not missing something obvious
-
Aug 19th, 2010, 06:26 AM
#15
Re: Parsing an XML file
 Originally Posted by chris128
I'm surprised it has nothing to do with LINQ when it is in an assembly that has LINQ in the name 
That's only because the extension methods is in that namespace and XElement are used in LINQ to XML but the code I showed is not LINQ.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|