March 01, 2021, 10:49:52 PM

Author Topic: [bmx] XmlToMax by Otus [ 1+ years ago ]  (Read 668 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bmx] XmlToMax by Otus [ 1+ years ago ]
« on: June 29, 2017, 12:28:39 AM »
Title : XmlToMax
Author : Otus
Posted : 1+ years ago

Description : <a href="http://code.google.com/p/maxmods/" target="_blank">LibXml[/url] 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
  1. SuperStrict
  2.  
  3. Import BRL.Reflection
  4.  
  5. Import BaH.LibXml
  6.  
  7. Type TNode Abstract
  8.        
  9.         Method AddChild(n:TNode) Abstract
  10.        
  11.         Method GetChildren:TList() Abstract
  12.        
  13.         Global typeid:TTypeId = TTypeId.ForName("TNode")
  14.        
  15. End Type
  16.  
  17. Function XmlToMax:TNode(x:TxmlNode)
  18.         Local t:TTypeId = TTypeId.ForName(x.GetName())
  19.         If Not t Return Null
  20.        
  21.         Local n:TNode = TNode(t.NewObject())
  22.         If Not n Return Null
  23.        
  24.         'Convers attributes to fields
  25.         Local l:TList = x.GetAttributeList()
  26.         If l
  27.                 For Local a:TxmlAttribute = EachIn l
  28.                         Local f:TField = t.FindField(a.GetName())
  29.                         If f Then f.Set n, a.GetValue()
  30.                 Next
  31.         End If
  32.        
  33.         'Convert child elements
  34.         l = x.GetChildren()
  35.         If l
  36.                 For Local c:TxmlNode = EachIn l
  37.                         n.AddChild XmlToMax(c)
  38.                 Next
  39.         End If
  40.        
  41.         Return n
  42. End Function
  43.  
  44. Function MaxToXml:TxmlNode(n:TNode, parent:TxmlNode = Null)
  45.         Local t:TTypeId = TTypeId.ForObject(n)
  46.        
  47.         Local x:TxmlNode
  48.         If parent
  49.                 x = parent.AddChild(t.Name())
  50.         Else
  51.                 x = TxmlNode.newNode(t.Name())
  52.         End If
  53.        
  54.         'Convert fields to attributes
  55.         For Local f:TField = EachIn t.EnumFields()
  56.                 If f.MetaData("xml") Then x.AddAttribute f.Name(), String(f.get(n))
  57.         Next
  58.        
  59.         'Convert child nodes
  60.         For Local c:TNode = EachIn n.GetChildren()
  61.                 MaxToXml c, x
  62.         Next
  63.        
  64.         Return x
  65. End Function


Comments :


Otus(Posted 1+ years ago)

 Example:
Code: [Select]
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:
Code: [Select]
<?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]

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal