Jump to content

.xsd's and .NET programming


chopsdogg

Recommended Posts

I am writing a little program right now for my own learning experiences. I have found that I can take the .XSD file at http://www.topografix.com/GPX/1/0/gpx.xsd use the xsd tool in the .NET SDK and generate my .vb file with all the classes created up. I can use this to create an instance of the XMLSeriallizer and use this to read a .gpx file from geocaching.com. However, a lot of the information that I see in the raw XML in the .gpx (e.g. log notes) do not show up in the object that is created.

 

I found out this is because Speakeasy has extended the gpx.xsd to the definition in cache.xsd found at http://www.Groundspeak.com/cache/1/0/cache.xsd. I tried doing the same process and creating the .vb file with all the classes using the .NET SDK tool xsd and the cache.xsd file. I am able to create up an instance of the XMLSerializer with the classes that are created. However, when I use this to read a .gpx file from geocaching.com, the only properties I see are the geocaching.com specific ones and they all have null values.

 

1. How do I read in both the standard GPX information as defined in http://www.topografix.com/GPX/1/0/gpx.xsd and the extended information as defined in http://www.Groundspeak.com/cache/1/0/cache.xsd in to the same object when deserilzing a .GPX file from geocaching.com?

 

2. Why are all the properties coming back null when using just the cache.xsd above? Or does that have to do with knowing how to do 1 above?

 

Here is some sample code below I am using. Note the cache1_0 namespace is what was generated from the XSD tool pointing toward http://www.Groundspeak.com/cache/1/0/cache.xsd.

 

Imports System.Xml.Serialization

Imports System.Xml

 

Public Class frmImport

 

Dim serializer As XmlSerializer = New XmlSerializer(GetType(GCBetter.cache1_0.cache))

Dim reader As XmlTextReader

Dim gpxfile As GCBetter.cache1_0.cache

 

Private Sub btnBrowse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBrowse.Click

If OpenFileDialog.ShowDialog().Equals(DialogResult.OK) Then

reader = New XmlTextReader(OpenFileDialog.FileName)

gpxfile = CType(serializer.Deserialize(reader), GCBetter.cache1_0.cache)

‘ Note the gpxfile object has some propties from the cache.xsd description, but they are all Nothing/null

reader.Close()

End If

End Sub

End Class

Link to comment

Have you considered parsing it without the XSD? I've never read an XML file using an XSD so I can't say that this is any better, just that this is how I've done it successfully.

 

	' Prompt user to select a file
Dim strFileName As String
strFileName = Application.GetOpenFilename("GPS GPX Files (*.gpx),*.gpx,All Files (*.*),*.*", , "Import GPX File", , False)
' User hit cancel
If strFileName = "False" Then Exit Sub

Dim objXMLDoc As New MSXML2.DOMDocument30
objXMLDoc.Load (strFileName)

' Error while parsing document
If objXMLDoc.parseError.errorCode <> 0 Then
	MsgBox "Invalid XML file."
	Exit Sub
End If

 

Now that you have objXMLDoc created, you can process it using IXMLDOMNodeList and IXMLDOMNode.

 

	Dim objNodeList As IXMLDOMNodeList, objNode As IXMLDOMNode
Dim strLatLon As String, intCt As Integer
Set objNodeList = objXMLDoc.selectNodes("//wpt")
For intCt = 1 To objNodeList.Length ' Loop through all wpts
	Set objNode = objNodeList.NextNode
	strLatLon = objNode.Attributes.getNamedItem("lat").Text & ", " & objNode.Attributes.getNamedItem("lon").Text
	MsgBox "Waypoint " & objNode.selectSingleNode("name/text()").Text & " (" & strLatLon & ")"
Next intCt

 

This requires the use of xPath notation (i.e. "name/text()").

Link to comment

Thank you for the reply. Reading the XML using XPath or something is trivial. I'm specifically trying to learn how to use the supplied .XSD files to create up native data structures automatically from a supplied file.

 

You should try this out to really see the benefits of doing it this way. It is pretty slick. If you use the XSD tool to generate your class from the gpx.xsd (version 1.0 for geocaching.com .gpx files), and then modify the code I have a bit to use that instead of the cache.xsd, you can get all the information from the gpx.xsd in to a strongly type object in .NET. I am just having problems getting the geocaching.com specific data out using this method and the supplied cache.xsd definition.

 

This is more educational purposes for myself, than trying to find something that works. I appreciate your solution that would surely work, but I really want to get this working using the supplied gpx.xsd and cache.xsd files. Any other suggestions?

Link to comment

Thank you for the reply. Reading the XML using XPath or something is trivial. I'm specifically trying to learn how to use the supplied .XSD files to create up native data structures automatically from a supplied file.

 

You should try this out to really see the benefits of doing it this way. It is pretty slick. If you use the XSD tool to generate your class from the gpx.xsd (version 1.0 for geocaching.com .gpx files), and then modify the code I have a bit to use that instead of the cache.xsd, you can get all the information from the gpx.xsd in to a strongly type object in .NET. I am just having problems getting the geocaching.com specific data out using this method and the supplied cache.xsd definition.

 

This is more educational purposes for myself, than trying to find something that works. I appreciate your solution that would surely work, but I really want to get this working using the supplied gpx.xsd and cache.xsd files. Any other suggestions?

Okay, first let me qualify this by saying that I'm just learning XSD, and I've resisted diving into .NET. Looking at the two files you linked, I had a hard time figuring out how they fit together. It's particularly hard without an actual Groundspeak gpx file to look at... Looking at the Groundspeak xsd, it just represents a snippet of a document, not the entire thing. You wouldn't be able to use it as a document schema because it's insufficient by itself (this is probably why you're getting Nothing or Null values).

 

So, looking at the main gpx schema file, obviously the <xsd:any> elements are where any extension points go. I think Groundspeak only extends the <wpt> elements with <cache> information. Looking here http://www.w3schools.com/schema/schema_complex_any.asp it seems that you have to create an xml schema instance (xsi) which references the different schemas you are using in a particular xml file. Maybe you have to do something similar with the .NET tools.

 

It seems that <xsd:any> blows up any strong typing, because it can take any element. So you're probably going to have a hard time mixing these two schema files unless you combine them on your own into a new xsd file, which is likely a bad idea.

 

Sorry for my stream-of-consciousness thoughts; maybe there's something helpful in there...

Link to comment

What you say is a great help and makes sense. I need to brush up on the XSD "syntax/language" a bit more. I didn't realize the cache.xsd only extended the WPT element instead of the whole thing. That does explain what I am seeing as you said. I think I'll have to use the gpx.xsd to get the main information and then use XPath or something like the previous posted suggested to get the rest unless I am missing something.

 

One other thing. How do I easily tell if I should be using version 1.1 or 1.0 of the gpx.xsd. Do I just need to XPath to the version node in my .GPX file or is there some other trick? Right now I have generated the native VB classes using the 1.1 and 1.0 files and do just that.

Link to comment

You can have the xsd.exe tool merge the xsd's for you like this:

xsd.exe gpx.xsd cache.xsd /c /l:vb

 

I haven't looked at how those particular xsd's relate, but I'm about to get into it. I'd love to share information on the subject.

 

By the way, Groundspeak uses version 1.0 of the gpx.xsd (http://www.topografix.com/GPX/1/0/gpx.xsd). You can tell by looking at the "header" of a gpx file from them.

Edited by StickMonsters
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...