xml convert

BlitzMax Forums/BlitzMax Programming/xml convert

I'd always thought bah, just a glorified text file whats so great about that

I recently implemented saving and loading of all the physics states for the objects in a project I'm doing at the moment and xml has made it so much easier

When adding new properties to my objects I simply and easily add them to the loader and saver in the knowledge that I can load my old data files...

If your worried about people hacking your saved games simply make the xml a password protected zip file with a custom file extension.

Please Give an example

heres the loader and saver
Function SaveWorld(fn:String)
	Local xmld:XmlDocument=New XmlDocument
	xmld.root=XMLNode.create(Null, "odemax", Null)
	Local camnode:XmlNode=XMLNode.create(xmld.root,"Camera",Null)
	Local Positionnode:XmlNode=XmlNode.create(camnode,"Position",Null)
	positionnode.AddAttribute("X",campos.x)
	positionnode.AddAttribute("Y",campos.y)
	positionnode.AddAttribute("Z",campos.z)
	Local Rotationnode:XmlNode=XmlNode.create(camnode,"Rotation",Null)
	Rotationnode.AddAttribute("X",camrot.x)
	Rotationnode.AddAttribute("Y",camrot.y)
	For Local o:OdeEnt=EachIn OdeObs
		Local node:XMLNode = XMLNode.create(xmld.root, "Object", Null)
		Local namenode:XmlNode=XmlNode.create(node,"Name",Null)
		namenode.AddAttribute("Value",o.name)
		Local typenode:XmlNode=XmlNode.create(node,"Type",Null)
		typenode.AddAttribute("Value",o.oType)
		Local sizenode:XmlNode=XmlNode.create(node,"Size",Null)
		sizenode.addAttribute("X",o.size.x)
		sizenode.addAttribute("Y",o.size.y)
		sizenode.addAttribute("Z",o.size.z)
		Local massnode:XmlNode=XmlNode.create(node,"Mass",Null)
		massnode.addAttribute("Value",o.totMass)
		Local posnode:XmlNode=XmlNode.create(node,"Position",Null)
		posnode.AddAttribute("X",o.ResetPos.x)
		posnode.AddAttribute("Y",o.ResetPos.y)
		posnode.AddAttribute("Z",o.ResetPos.z)
		Local rot1node:XmlNode=XmlNode.create(node,"Rotation1",Null)
		For Local i:Int=0 To 3
			rot1node.AddAttribute("M"+i,o.ResetRot[i])
		Next
		Local rot2node:XmlNode=XmlNode.create(node,"Rotation2",Null)
		For Local i:Int=4 To 7
			rot2node.AddAttribute("M"+i,o.ResetRot[i])
		Next
		Local rot3node:XmlNode=XmlNode.create(node,"Rotation3",Null)
		For Local i:Int=8 To 11
			rot3node.AddAttribute("M"+i,o.ResetRot[i])
		Next
		Local rot4node:XmlNode=XmlNode.create(node,"Rotation4",Null)
		For Local i:Int=12 To 15
			rot4node.AddAttribute("M"+i,o.ResetRot[i])
		Next
		Local staticnode:XmlNode=XmlNode.create(node,"Static",Null)
		If o.body=Null Then
			staticnode.AddAttribute("Value","True")
		Else
			staticnode.AddAttribute("Value","False")
		EndIf
		Local meshnamenode:XmlNode=XmlNode.create(node,"MeshName",Null)
		meshnamenode.AddAttribute("Value",o.meshname)		
	Next

	xmld.save(fn)	
EndFunction

Function LoadWorld(fn:String)

	Local xmld:XmlDocument=XmlDocument.load(fn)

	ClearList(OdeObs)
	If xmld <> Null Then
		For Local o:OdeEnt=EachIn OdeObs
			dBodyDestroy(o.body)
			dGeomDestroy(o.geom)
			o=Null
		Next

		For Local child:XMLNode = EachIn xmld.root.children
			If child.name="Object" Then
				Local pos:TVec3=New TVec3
				Local size:TVec3=New TVec3
				Local m:Float[16]
				Local t:Int
				Local name:String
				Local mass:Float
				Local static:Int
				Local meshname:String
			
				For Local obj:XMLNode = EachIn child.children
					
					Select obj.name
						Case "Type"
							t=Int(obj.getAttr("Value").value)
						Case "Name"
							name=obj.getAttr("Value").value
						Case "Size"
							size.x=Float(obj.getAttr("X").value)
							size.y=Float(obj.getAttr("Y").value)
							size.z=Float(obj.getAttr("Z").value)
						Case "Position"
							pos.x=Float(obj.getAttr("X").value)
							pos.y=Float(obj.getAttr("Y").value)
							pos.z=Float(obj.getAttr("Z").value)
						Case "Rotation1"
							m[0]=Float(obj.getAttr("M0").value)
							m[1]=Float(obj.getAttr("M1").value)
							m[2]=Float(obj.getAttr("M2").value)
							m[3]=Float(obj.getAttr("M3").value)
						Case "Rotation2"
							m[4]=Float(obj.getAttr("M0").value)
							m[5]=Float(obj.getAttr("M1").value)
							m[6]=Float(obj.getAttr("M2").value)
							m[7]=Float(obj.getAttr("M3").value)
						Case "Rotation3"
							m[8]=Float(obj.getAttr("M0").value)
							m[9]=Float(obj.getAttr("M1").value)
							m[10]=Float(obj.getAttr("M2").value)
							m[11]=Float(obj.getAttr("M3").value)
						Case "Rotation4"
							m[12]=Float(obj.getAttr("M0").value)
							m[13]=Float(obj.getAttr("M1").value)
							m[14]=Float(obj.getAttr("M2").value)
							m[15]=Float(obj.getAttr("M3").value)
						Case "Mass"
							mass=Float(obj.getAttr("Value").value)
						Case "Static"
							If obj.getAttr("Value").value="True" Then
								static=True
							Else
								static=False
							EndIf
						Case "MeshName"
							meshname=obj.getAttr("Value").value	
					EndSelect
				Next
				
				Local o:OdeEnt=CreateOdeOb(OdeSpace,t,[pos.x,pos.y,pos.z],[size.x,size.y,size.z],mass,meshname)
	
				For Local i:Int=0 To 15
					o.ResetRot[i]=m[i]
				Next
				o.name=name
				o.ResetPos.x=pos.x;o.ResetPos.y=pos.y;o.ResetPos.z=pos.z
				dbodySetRotation(o.body,Varptr o.ResetRot[0])
				If static Then 
					dbodydestroy(o.body)
					o.body=Null
				EndIf
			EndIf
			
			If child.name="Camera" Then
				For Local cam:XMLNode=EachIn child.children
					Select cam.name
						Case "Position"
							CamPos.x=Float(cam.getAttr("X").value)
							CamPos.y=Float(cam.getAttr("Y").value)
							CamPos.z=Float(cam.getAttr("Z").value)
						Case "Rotation"
							CamRot.x=Float(cam.getAttr("X").value)
							CamRot.y=Float(cam.getAttr("Y").value)
					EndSelect
				Next
			EndIf
		Next
		
		' clear up memory usage
		xmld.root.dispose()
		xmld = Null
		
	End If
End Function


this is an example file
<?xml version="1.0" encoding="UTF-8" ?>

<odemax>
    <Camera>
        <Position X="9.27567482" Y="29.0205994" Z="51.5746574"/>
        <Rotation X="8.00000000" Y="714.000000"/>
    </Camera>
    <Object>
        <Name Value="no name"/>
        <Type Value="3"/>
        <Size X="1.00000000" Y="1.00000000" Z="1.00000000"/>
        <Mass Value="1.00000000"/>
        <Position X="0.000000000" Y="4.00000000" Z="0.000000000"/>
        <Rotation1 M0="1.00000000" M1="0.000000000" M2="0.000000000" M3="0.000000000"/>
        <Rotation2 M4="0.000000000" M5="1.00000000" M6="0.000000000" M7="0.000000000"/>
        <Rotation3 M8="0.000000000" M9="0.000000000" M10="1.00000000" M11="0.000000000"/>
        <Rotation4 M12="0.000000000" M13="0.000000000" M14="0.000000000" M15="0.000000000"/>
        <Static Value="True"/>
        <MeshName Value="terrain.ms3d"/>
    </Object>
    <Object>
        <Name Value="Spike1"/>
        <Type Value="3"/>
        <Size X="1.00000000" Y="1.00000000" Z="1.00000000"/>
        <Mass Value="1.00000000"/>
        <Position X="0.000000000" Y="31.3498116" Z="0.000000000"/>
        <Rotation1 M0="1.00000000" M1="0.000000000" M2="0.000000000" M3="0.000000000"/>
        <Rotation2 M4="0.000000000" M5="1.00000000" M6="0.000000000" M7="0.000000000"/>
        <Rotation3 M8="0.000000000" M9="0.000000000" M10="1.00000000" M11="0.000000000"/>
        <Rotation4 M12="0.000000000" M13="0.000000000" M14="0.000000000" M15="0.000000000"/>
        <Static Value="False"/>
        <MeshName Value="spikes.ms3d"/>
    </Object>
    <Object>
        <Name Value="box"/>
        <Type Value="0"/>
        <Size X="2.84999824" Y="1.21999979" Z="4.19000149"/>
        <Mass Value="1.00000000"/>
        <Position X="0.000000000" Y="23.6499290" Z="0.000000000"/>
        <Rotation1 M0="1.00000000" M1="0.000000000" M2="0.000000000" M3="0.000000000"/>
        <Rotation2 M4="0.000000000" M5="1.00000000" M6="0.000000000" M7="0.000000000"/>
        <Rotation3 M8="0.000000000" M9="0.000000000" M10="1.00000000" M11="0.000000000"/>
        <Rotation4 M12="0.000000000" M13="0.000000000" M14="0.000000000" M15="0.000000000"/>
        <Static Value="False"/>
    </Object>
    <Object>
        <Name Value="spike2"/>
        <Type Value="3"/>
        <Size X="1.00000000" Y="1.00000000" Z="1.00000000"/>
        <Mass Value="1.00000000"/>
        <Position X="8.45001411" Y="29.6498375" Z="0.000000000"/>
        <Rotation1 M0="1.00000000" M1="0.000000000" M2="0.000000000" M3="0.000000000"/>
        <Rotation2 M4="0.000000000" M5="1.00000000" M6="0.000000000" M7="0.000000000"/>
        <Rotation3 M8="0.000000000" M9="0.000000000" M10="1.00000000" M11="0.000000000"/>
        <Rotation4 M12="0.000000000" M13="0.000000000" M14="0.000000000" M15="0.000000000"/>
        <Static Value="False"/>
        <MeshName Value="spikes.ms3d"/>
    </Object>
</odemax>


When doing
Local meshnamenode:XmlNode=XmlNode.create(node,"MeshName",Null)

You can just do this instead
Local meshnamenode:XmlNode=node.AddChild("MeshName")


Also, I've released a new version of the library with a few fixes.

must have missed that in the doc's ;p

Is there any difference?

Nope, just a convenience thing.

okay thanks!

I hope people have been giving you feedback, makes you wonder if its worth contributing to the "community" somtimes...

Hey Chris, I thought you said xml was just a glorified text file, eh? *nudge* *nudge* :-p

But don't you think you'd have been better using a custom binary format for all that? It would have taken up a tenth of your valuable disk space :-)

lol - nice try brucey ;) ascii zip's *rather* well!

Thanks For the sample Chris :)