Just don't get this XML stuff

hog

Well-known member
Joined
Mar 17, 2003
Messages
984
Location
UK
Ok I am missing something here as I am not being able to get single values from an XML file.

The file contains this:

<?xml version="1.0" encoding="utf-8" ?>

<config>
<location>Pluto</location>
<notify>0</notify>
<notifypreriod>3</notifypreriod>
</config>

I am trying to read in the three node values, location, notify and period using this code:

Code:
Dim xpathVersion As XPathDocument = New XPathDocument(strXMLcfg)

 create a path navigator

xPath = xpathVersion.CreateNavigator

 move to the first child node in the file I presume it to be location

xPath.MoveToFirstChild()

 get the location of this running apps data source

strLocation = xPath.Value

xPath.MoveToNext()

blnNotify = xPath.Value

xPath.MoveToNext()

intPeriod = xPath.Value

MessageBox.Show(strLocation & ControlChars.CrLf & blnNotify & ControlChars.CrLf & intPeriod)

On the line that assigns xPath.Value to strLocation rather than just Pluto being assigned it gets PlutoNo3, then the code falls over at the line where it attempts to assign the next xPath.Value to blnNotify as it is still PlutoNo3

The messagebox is there purely for test purposes.

So am I missing somethin fundamental here:confused:
 
When ever im loading configs from XML what i tend to do is load it into a dataset read whats needed from within the dataset then dispose of the dataset.

Andy
 
After calling MoveToFirstChild(), check the value of xPath.Name;
it looks like the first child is the <config> node rather than the
<location> node, so the Name property will be "config". If this is
the case, then just call MoveToFirstChild() twice to advance to the
<location> node from the <config> node.
 
Weird as from the book I am reading I would think that config was the parent and the others were child nodes. But the messagebox confirms that config is the first child?

a_jam, so how do you go about reading an xml file into a dataset?
 
Simple question that may help

Is your xml data defined by a dtd or a schema? Either of these two methods define the structure and elements in an xml document. For example:

<?xml version="1.0" encoding="utf-8" ?>

<!DOCTYPE config [
<!ELEMENT planet (#PCDATA)>
<!ELEMENT notify (#PCDATA)>
<!ELEMENT location (#PCDATA)>
]>


<config>
<location>Pluto</location>
<notify>0</notify>
<notifypreriod>3</notifypreriod>
</config>

This xml now validates through an xml dtd validator. The dtd can be included in the xml document itself or refernced by the xml document. The above code shows that the parent node contains the elements planet, notify, and location.This way when you use it in vb.net it should reconize that <config> is the parent node. Another way, even better is to use a schema which can be reused and is supposed to be more efficient although I personally havent used them yet.
 
<vb>
Here is an example of a schema document.

- <Schema xmlns="urn:schemas-microsoft-com:xml-data" xmlns:dt="urn:schemas-microsoft-com:datatypes">
<AttributeType name="C" required="yes" dt:type="string" />
<AttributeType name="F" required="yes" dt:type="string" />
- <ElementType name="LOW">
<attribute type="C" />
<attribute type="F" />
</ElementType>
- <ElementType name="HI">
<attribute type="C" />
<attribute type="F" />
</ElementType>
<AttributeType name="VALUE" required="yes" dt:type="enumeration" dt:values="SUNNY PARTLYSUNNY PARTLYCLOUDY CLOUDY RAIN SNOW" />
- <ElementType name="SKIES">
<attribute type="VALUE" />
</ElementType>
<AttributeType name="NAME" required="yes" dt:type="string" />
- <ElementType name="CITY" content="mixed">
<attribute type="NAME" />
<element type="SKIES" />
<element type="HI" />
<element type="LOW" />
</ElementType>
- <ElementType name="STATE" content="mixed">
<attribute type="NAME" />
<element type="CITY" />
</ElementType>
- <ElementType name="WEATHERREPORT" content="eltOnly">
<element type="STATE" />
</ElementType>
</Schema>

</vb>

<vb>
And here it is being referenced in an xml document.
<?xml version="1.0" ?>
- <WEATHERREPORT xmlns="x-schema:WeatherSchema.xml">
- <STATE NAME="California">
- <CITY NAME="Los Angeles">
<SKIES VALUE="PARTLYSUNNY" />
<HI C="31" F="87" />
<LOW C="18" F="65" />
Partly cloudy
</CITY>
- <CITY NAME="Sacramento">
<SKIES VALUE="SUNNY" />
<HI C="36" F="97" />
<LOW C="17" F="64" />
Sunny and hot.
</CITY>
- <CITY NAME="San Diego">
<SKIES VALUE="PARTLYSUNNY" />
<HI C="26" F="78" />
<LOW C="19" F="67" />
</CITY>
- <CITY NAME="San Fransisco">
<SKIES VALUE="PARTLYCLOUDY" />
<HI C="26" F="79" />
<LOW C="14" F="58" />
Partly cloudy and humid
</CITY>
- <CITY NAME="Truckee">
<SKIES VALUE="RAIN" />
<HI C="32" F="89" />
<LOW C="11" F="52" />
Scattered thunderstorms
</CITY>
</STATE>
- <STATE NAME="New Jersey">
- <CITY NAME="Newark">
<SKIES VALUE="PARTLYSUNNY" />
<HI C="36" F="97" />
<LOW C="21" F="71" />
Partly sunny, breezy and humid
</CITY>
- <CITY NAME="Trenton">
<SKIES VALUE="PARTLYCLOUDY" />
<HI C="32" F="90" />
<LOW C="18" F="65" />
Partly cloudy and humid
</CITY>
- <CITY NAME="Princeton">
<SKIES VALUE="RAIN" />
<HI C="33" F="92" />
<LOW C="20" F="68" />
Thundershowers
</CITY>
- <CITY NAME="White Meadow Lake">
<SKIES VALUE="SUNNY" />
<HI C="24" F="85" />
<LOW C="21" F="70" />
Sunny, clear skies, breezy and warm.
</CITY>
</STATE>
- <STATE NAME="Washington">
- <CITY NAME="Seattle">
<SKIES VALUE="RAIN" />
<HI C="20" F="68" />
<LOW C="15" F="59" />
Raining on and off throughout the day.
</CITY>
- <CITY NAME="Yakima">
<SKIES VALUE="PARTLYSUNNY" />
<HI C="23" F="73" />
<LOW C="14" F="57" />
Partly sunny after morning clouds
</CITY>
- <CITY NAME="Redmond">
<SKIES VALUE="SNOW" />
<HI C="2" F="35" />
<LOW C="-7" F="20" />
Snowstorms in the afternoon
</CITY>
</STATE>
</WEATHERREPORT>
</vb>
 
Woooh too much in one hit dude! Your talking to someone who is just starting to use xml so I dont get what you are talking about.

The xml below I created manually:

<?xml version="1.0" encoding="utf-8" ?>

<config>
<location>Pluto</location>
<notify>0</notify>
<notifypreriod>3</notifypreriod>
</config>

I am now using this to obtain the three values of location, notify and period:

Code:
Dim xPath As XPathNavigator

Dim strXMLcfgPath As String = Application.StartupPath

Dim strXMLcfg As String = strXMLcfgPath & "\MaSCScfg.xml"

 check whether the cfg file exists, create it if it does not.

If System.IO.File.Exists(strXMLcfg) Then

     open the xml file which stores the required config data

     Dim xpathConfig As XPathDocument = New XPathDocument(strXMLcfg)

       create a path navigator

      xPath = xpathConfig.CreateNavigator

       move to the first child node in the file

      xPath.MoveToFirstChild()
      xPath.MoveToFirstChild()

       get the location of this running apps data source

      m_strLocation = xPath.Value

      xPath.MoveToNext()

       get the boolean to determine notification choice

       m_blnNotify = xPath.Value

       xPath.MoveToNext()

       get the notification week period value

       m_intPeriod = xPath.Value

 Else

        code to create xml file to go here

 End If

is this correct? seems weird having to call xPath.MoveToFirstChild() twice??
 
Okay, first you created the xml manually, meaning you probably wrote it in notepad and saved it as .xml, right? That is only part of creating an xml document. If you do not define its structure then vb will not know which is a parent node and which is a child. That is where my first post comes in. Add the dtd part of the code from my first response into your xml document code, then save it (I already ran it through a validator so I know it validates ok) Now try reading it into your vb code and see if the first child node is now <planet>. It should work fine now because the dtd defines <config> as the parent containing elements <planet><notify><location>. The second reply was just an example of what a schema and xml referencing that schema looks like.
 
Sorry dude, call the elements <location><notify>and <notifyperiod> not <planet><notify> and <location> as I put in the xml example above, I was doing it from memory of what I thought you called the xml tags.My goof.
 
Aha, righty ho ta muchly, I shall play with this and get back to you thanks.

You were right I created the xml file in notepad, so silly question....where should I create?
 
DOH! in fact thinking about this I did create it in the IDE. I added an XML file to my project, typed in the bits and saved it.

So did I do something else wrong??
 
Sorry Hog been preocuppied with playing games DOH!, but i must add Day of Defeat is great.

Anyway to load an XML file into dataset see below

Code:
                Dim MyDataset As New Dataset
                Dim MyXMLReader As Xml.XmlTextReader = New Xml.XmlTextReader(Application.StartupPath & "\MyXML.XML")
                ReportDataset.ReadXml(MyXMLReader)
                MyXMLReader .Close()
                 And now it in the dataset Table(0)

Hope it help m8 :)

Andy
 
mbf114 I put your bit in but still had to call MoveToFirstChild twice to get to the location node?

a_jam, tried your method and it works, but I cant help thinking that there shold be a better way to read in xml. Im sure the actual tools for the job are fine, just can suss them out at the mo:(
 
OK, Im up the creek without a paddle here so Ill go cap in hand to you guys as I desperately need a quick fix for this.

Could someone supply me with a code snippet that will do the following:

Open an xml file and read in the content if it exists
Create an xml file if it does not exist with the three nodes set to nothing
write/save user changes back to the xml file.

This is the content of the file:

Code:
<?xml version="1.0" encoding="utf-8" ?> 

<config>
	<location>Wellingborough</location>
	<notify>0</notify>
	<notifypreriod>3</notifypreriod>
</config>

and this is what Im using to create it if it doesnt exist

Code:
               Dim xmlConfigTextWriter As XmlTextWriter = New XmlTextWriter(strXMLcfg, Nothing)

                xmlConfigTextWriter.Formatting = System.Xml.Formatting.Indented
                xmlConfigTextWriter.WriteStartDocument(False)
                xmlConfigTextWriter.WriteStartElement("config")
                xmlConfigTextWriter.WriteStartElement("location", Nothing)
                xmlConfigTextWriter.WriteEndElement()
                xmlConfigTextWriter.WriteStartElement("notify", Nothing)
                xmlConfigTextWriter.WriteEndElement()
                xmlConfigTextWriter.WriteStartElement("notifyperiod", Nothing)
                xmlConfigTextWriter.WriteEndElement()
                xmlConfigTextWriter.WriteEndElement()
                
                Write the XML to file and close the myXmlTextWriter
                xmlConfigTextWriter.Flush()
                xmlConfigTextWriter.Close()

which results in this?

[/code]

<?xml version="1.0" standalone="no"?>
<config>
<location />
<notify />
<notifyperiod />
</config>

[/code]

please anyone...can u help:(:(:(
 
Ive thought of an easier solution: XML serialization. It does all
of the reading and writing formatting for you, and you can
access all the values as the properties of a class.

[mshelp]ms-help://MS.VSCC/MS.MSDNVS/cpguide/html/cpconintroducingxmlserialization.htm[/mshelp]

Its something to consider. :)

As for your question, there is a ton of code and explanations in
MSDN. Read it through and you should have a good idea. There
are links [mshelp=ms-help://MS.VSCC/MS.MSDNVS/cpguide/html/cpconxmldocumentobjectmodeldom.htm]here[/mshelp] regarding reading and writing files with the XmlReader and XmlWriter.
 
Nah, I think I will stick with the registry, much simpler and quicker than this xml milarky.

Ive been at this for over a week now and am still no further forward. Using Saveseting and Getsetting does exactly what I want so why bother with xml which for my purposes is the same as creating an ini file which is well out of date??
 
Just another word from me whilst Im on me soap box. A quote from SAMs Teach Yourself Visual Basic .Net

XML is not going to solve world hunger, prevent war, or even make coffee for you in the morning. all it wants to do is tell you about a block of text. Many people try to make XML the solution to everything, or try to apply it where it might not, or should not be fit. If it seems like it is causing more problems than you want to solve, or even if it isnt solving any problems, dont use it, find another, better solution.

This says it all for me. I only want to check three values and to me xml is just too much like hard work. Less than ten minutes my code is reverted to the registry and is doing exactly as I want:)

Maybe at a later date I might find I need to use xml for far greater things, but at the moment it just aint so :)
 
Back
Top