XML question

BlitzMax Forums/Brucey's Modules/XML question

Ravl(Posted 2013) [#1]
I cannot understand how to read some data.

I have this xml file based on the Tiled program:


<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" orientation="orthogonal" width="30" height="30" tilewidth="40" tileheight="40">
 <tileset firstgid="1" name="GRS2ROC" tilewidth="40" tileheight="40">
  <image source="C:/MonkeyPro69/modules/fantomEngine/examples/TileMaps/Tiled/Tiled.data/maps/GRS2ROC.png" width="640" height="480"/>
 </tileset>
 <layer name="Tile Layer 1" width="30" height="30">
  <data>
   <tile gid="68"/>
   <tile gid="68"/>
   .
   .
   .
   <tile gid="68"/>
   <tile gid="0"/>
   <tile gid="0"/>
  </data>
 </layer>
</map>


I figured out how to search for a node and I have found:
-'tileset'
-'layer'

then, I am searching in the 'layer' node and I found:
-'data'

The question is how to read all the "<tile gid="68"/>" values ??

here it is my code:


	Method parseXMLFile(docname:String)
		Local doc:TxmlDoc
		Local node:TxmlNode
	
		doc = TxmlDoc.parseFile("graphics\" + docname)
			
		If doc = Null Then
			Print "Document not parsed successfully."
			Return
		End If
	
		node = doc.GetRootElement()
	
		If node = Null Then
			Print "empty document"
			doc.free()
			Return
		End If	

		
		Local children:TList = node.getChildren()
		
		'read scene info
		For node = EachIn children
			'Print node.getName()
			If node.getName() = "tileset" Then
				'Print "found a tileset"
				parseTilesetNode(doc, node)
			End If
			
			If node.getName() = "layer" Then
				'Print "found a tileset"
				parseLayerNode(doc, node)
			End If				
			
		Next
				
		doc.free()
		Return
	End Method

	Method parseTilesetNode(doc:TxmlDoc, node:TxmlNode)
		Local textureName:String
		textureName = node.getAttribute("name")					
		Print "textureName = " + textureName
		
		Return		
	End Method
	
	Method parseLayerNode(doc:TxmlDoc, node:TxmlNode)
		Local layerWidth:String
		Local layerHeight:String				
		layerWidth = node.getAttribute("width")
		layerHeight = node.getAttribute("height")		
		
		Local children:TList = node.getChildren()
			
			For node = EachIn children
				If node.getName() = "data" Then
					'parseDataNode(doc, node)


				End If
			Next
		
		Return		
	End Method

	Method parseDataNode(doc:TxmlDoc, node:TxmlNode)
		
	End Method




Brucey(Posted 2013) [#2]
Hallo.

There are several ways to go about this. One way, like you've done, is just have lots of methods parsing each node separately.

Another way is to have an Object structure which resembles your tree. Each Object could subclass a "node" base type, and have a "decode" method of some kind. This method would know how to process only it's own matching node type. So, your TLayer would know it had a data node, and so on.
For small xml trees, this can be an simple way to build your xml load/save code, as well as having a ready-to-use object tree.

Yet another way, if you are searching for specific kinds of nodes within a tree, is to use XPath. As its name suggests, you can search the tree based on a path of sorts.

For example, I can get a list of all tile nodes with a gid of 68 using this search text :
//tile[@gid=68]

(find all nodes of name "tile", with attribute "gid" equal to "68")

If you look in the libxml module docs, there's an xpath.bmx example, that you can play around with. Replace the file with yours, and try the xpath.

And there's some syntax available here : http://www.w3schools.com/xpath/xpath_syntax.asp

:o)


Ravl(Posted 2013) [#3]
I solved it using the 1st method with a lot of methods. Anyway I really have to learn all the stuff about xml because sometimes I am stuck in little issues like that.

Thanks,