[bmx] XmlToMax by Otus [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:39

Previous topic - Next topic

BlitzBot

Title : XmlToMax
Author : Otus
Posted : 1+ years ago

Description : <a href="http://code.google.com/p/maxmods/" target="_blank">LibXml</a> required!

Converts an XML file to object tree of user defined types and the other way around using LibXml and Reflection.

To load an XML file, all you need to do is extend all supported object types from TNode. The names of XML elements and attributes are matched with types and fields.

To save an XML file, you also need to tag fields that you want to save with {xml}. Example in first post should be self explanatory.


Code :
Code (blitzmax) Select
SuperStrict

Import BRL.Reflection

Import BaH.LibXml

Type TNode Abstract

Method AddChild(n:TNode) Abstract

Method GetChildren:TList() Abstract

Global typeid:TTypeId = TTypeId.ForName("TNode")

End Type

Function XmlToMax:TNode(x:TxmlNode)
Local t:TTypeId = TTypeId.ForName(x.GetName())
If Not t Return Null

Local n:TNode = TNode(t.NewObject())
If Not n Return Null

'Convers attributes to fields
Local l:TList = x.GetAttributeList()
If l
For Local a:TxmlAttribute = EachIn l
Local f:TField = t.FindField(a.GetName())
If f Then f.Set n, a.GetValue()
Next
End If

'Convert child elements
l = x.GetChildren()
If l
For Local c:TxmlNode = EachIn l
n.AddChild XmlToMax(c)
Next
End If

Return n
End Function

Function MaxToXml:TxmlNode(n:TNode, parent:TxmlNode = Null)
Local t:TTypeId = TTypeId.ForObject(n)

Local x:TxmlNode
If parent
x = parent.AddChild(t.Name())
Else
x = TxmlNode.newNode(t.Name())
End If

'Convert fields to attributes
For Local f:TField = EachIn t.EnumFields()
If f.MetaData("xml") Then x.AddAttribute f.Name(), String(f.get(n))
Next

'Convert child nodes
For Local c:TNode = EachIn n.GetChildren()
MaxToXml c, x
Next

Return x
End Function


Comments :


Otus(Posted 1+ years ago)

 Example:
SuperStrict

Framework BRL.StandardIO

Import "XmlToMax.bmx"

Type TBase Extends TNode

Field childlist:TList = New TList

Method AddChild(n:TNode)
childlist.addLast n
End Method

Method GetChildren:TList()
Return childlist
End Method

End Type

Type TRoot Extends TBase

Field name:String {xml}

Field count:Int

Method AddChild(n:TNode)
childlist.addLast n
count :+ 1
End Method

Method Output()
Print name + " contains "+count+" items:"
For Local i:TItem = EachIn childlist
Print i.name+": $"+i.value
Next
End Method

End Type

Type TItem Extends TBase

Field name:String {xml}

Field value:Int {xml}

End Type

Local r:TRoot = New TRoot
r.name = "Collection"

For Local j% = 1 To 10
Local i:TItem = New TItem
i.name = "Item #"+j
i.value = 100*j
r.AddChild i
Next

r.Output()

Print "Saving..."

Local x:TxmlNode = MaxToXml(r)

Local doc:TxmlDoc = TxmlDoc.NewDoc("1.0")
doc.SetRootElement x
doc.SaveFormatFile "test.xml", True

Print "Loading..."

doc = TxmlDoc.ParseFile("test.xml")
x = doc.GetRootElement()
Local r2:TRoot = TRoot(XmlToMax(x))

r2.Output()
Produced XML:<?xml version="1.0"?>
<TRoot name="Collection">
  <TItem name="Item #1" value="100"/>
  <TItem name="Item #2" value="200"/>
  <TItem name="Item #3" value="300"/>
  <TItem name="Item #4" value="400"/>
  <TItem name="Item #5" value="500"/>
  <TItem name="Item #6" value="600"/>
  <TItem name="Item #7" value="700"/>
  <TItem name="Item #8" value="800"/>
  <TItem name="Item #9" value="900"/>
  <TItem name="Item #10" value="1000"/>
</TRoot>



Hezkore(Posted 1+ years ago)

 Wow, this is pretty neat.Wish I had found this earlier! [/i]