About Monkey 2 › Forums › Monkey 2 Development › XML module
This topic contains 22 replies, has 5 voices, and was last updated by 
 Arjailer
 2 years, 6 months ago.
- 
		AuthorPosts
 - 
		
			
				
September 16, 2016 at 5:15 am #3963
Is anyone coding an XML module for MX2?
If not, any suggestions for a C/C++ XML library to wrap? Or maybe a “native” BlitzMax or Monkey1 solution to port?
I just need something simple: load and parse basic but “well-formed” XML and create a DOM-like tree structure from it.
September 16, 2016 at 6:15 am #3964tinyxml2 looks very tidy…
http://www.grinninglizard.com/tinyxml2/
The mx2 API would probably look something like:
Monkey12345678910111213141516171819202122232425262728293031323334353637Class XMLNodeMethod GetDocument:XMLDocument()Method NoChildren:Bool()Method Parent:XMLNode()Method FirstChild:XMLNode()Method NextSibling:XMLNode()Method Value:String()EndClass XMLDocument Extends XMLNodeEndClass XMLComment Extends XMLNodeEndClass XMLElement Extends XMLNodeEndClass XMLDeclaration Extends XMLNodeEndClass XMLText Extends XMLNodeEndClass XMLUnknown Extends XMLNodeEndFunction LoadXMLDocument:XMLDocument( path:String )EndThere’s more methods, but that’s the jist of it, just yer basic tree. Is that the sort of thing you’re after?
September 16, 2016 at 6:58 am #3965I converted skn3’s Monkey X xml module to Monkey 2. It’s pure Monkey 2 code with no dependencies. I don’t have it on this PC, but I could post it later if you’re interested.
TinyXML looks good though
September 16, 2016 at 7:10 am #3966I’ve made a pretty good start on tinyxml2, but the more the merrier! Wish people would staring using that module manager thingy though…
Anyway, I’m more of a JSON guy myself, but is this pretty much what you need from an xml module?
Monkey123456789101112131415161718192021222324252627282930313233343536Function Dump( node:XMLNode,indent:String )Print indent+node.Value()Local child:=node.FirstChild()While childDump( child,indent+" " )child=child.NextSibling()WendEndFunction Main()Local xml:=LoadString( "asset::dream.xml" )Local doc:=New XMLDocumentIf doc.Parse( xml )<>XMLError.XML_SUCCESSPrint "Failed to parse"ReturnEndifPrint "Parsed!"Dump( doc,"" )doc.Destroy()Print "Bye!"End…which produces…
Monkey12345678910111213141516171819202122232425xml version="1.0"DOCTYPE PLAY SYSTEM "play.dtd"PLAYTITLEA Midsummer Night's DreamFMPText placed in the public domain by Moby Lexical Tools, 1992.PSGML markup by Jon Bosak, 1992-1994.PXML version by Jon Bosak, 1996-1998.PThis work may be freely copied and distributed worldwide.PERSONAETITLEDramatis PersonaePERSONATHESEUS, Duke of Athens.PERSONAEGEUS, father to Hermia.PGROUPPERSONA...etc...September 16, 2016 at 8:33 am #3970@Mark
Anyway, I’m more of a JSON guy myself, but is this pretty much what you need from an xml module?
That’s exactly what I’m looking for.
Regarding JSON, XML, etc. I’m usually an INI or CSV or pure binary data guy, but I’m working on a project where I can actually see the benefit of using XML-formatted data. JSON has never really “gelled” with me, I tend to avoid it.
Wish people would staring using that module manager thingy though…
Indeed, that would be nice. :). I have a few half-finished modules I hope to finish soon. I’ll upload them when I do.
That Monkey1 module by skn3 is the one I had planned to port if nobody else had started on an XML module…
September 16, 2016 at 9:15 am #3971Here’s the xml parser.
I might upload it as a module later, but between adding a demo app and adding documentation it’s actually a fair amount of work.
Edit: Especially as it’s not originally my code so documenting it might be “fun”
Attachments:
September 16, 2016 at 9:18 am #3973I do have Linq-like extension methods for List<T> and Stack<T> that I would like to upload to the module manager. Might work on that a bit today.
September 16, 2016 at 11:34 am #3977Hmmm … do extension methods not work in modules?
The module builds but I’m getting pretty much empty .cpp source files in my windows_debug folder and if I try to use any of the extension methods I get “undefined reference” errors.
It all works fine when built as an app where the .cpp source files contain everything I’d expect to see.
If I build the app without actually referencing or using any of the extension methods I get the same empty .cpp source files as I’m seeing in the module. This makes sense for building an app ‘cos it’s only building what it needs to, but I wouldn’t have thought a module would do that?
Am I missing something about building modules?
September 17, 2016 at 3:21 am #3984@Mark
Woohoo! Just tried the latest GIT release and have been playing around with the tinyxml module. Works nicely so far. Thanks!
Here’s an example that builds a mojox tree from that “dream.xml” file included with the banana:
[/crayon]Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384[crayon-5cb9d7b288a31419683603 inline="true" ]#Import "<std>"#Import "<mojo>"#import "<mojox>"#Import "<tinyxml2>"#Import "dream.xml"Using std..Using mojo..Using mojox..Using tinyxml2..Function Main()New AppInstanceNew MyWindow("asset::dream.xml")App.Run()EndClass MyWindow Extends WindowField _tree:TreeViewMethod New(url:String)Super.New("XML TreeView Test", 640, 480, WindowFlags.Resizable)Local xml := LoadString(url)Local doc := New XMLDocument()If doc.Parse(xml) <> XMLError.XML_SUCCESSPrint "Failed to parse: " + urlReturnEndifLocal _tree := New TreeView_tree.RootNode.Text = "XML document"AddXMLNodeToTree(doc, _tree.RootNode)ContentView = _treedoc.Destroy()EndMethod AddXMLNodeToTree(xmlNode:XMLNode, parent:TreeView.Node)Local str := ""If xmlNode.ToElement()str += "<" + xmlNode.Value() + ">"Elsestr += xmlNode.Value()EndifLocal treeNode:TreeView.NodeIf strtreeNode = New TreeView.Node(str, parent)EndifLocal xmlChild := xmlNode.FirstChild()While xmlChildIf Not xmlChild.NoChildren()If treeNode Then parent = treeNodeEndifAddXMLNodeToTree(xmlChild, parent)xmlChild = xmlChild.NextSibling()WendEndEndThanks for posting your code. I’ll experiment with that later, see how it compares to Mark’s tinyxml wrapper solution.
September 17, 2016 at 10:31 am #3985Another tinyxml2 example with element attributes and “embedded XML”:
[/crayon]Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134[crayon-5cb9d7b28d90b354693032 inline="true" ]#Import "<std>"#Import "<mojo>"#import "<mojox>"#Import "<tinyxml2>"Using std..Using mojo..Using mojox..Using tinyxml2..Function Main()New AppInstanceNew MyWindow()App.Run()EndClass MyWindow Extends WindowField _tree:TreeViewMethod New()Super.New("XML TreeView Test", 640, 480, WindowFlags.Resizable)Local xml := LoadEmbeddedXMLString()Local doc := New XMLDocument()If doc.Parse(xml) <> XMLError.XML_SUCCESSPrint "Failed to parse embedded XML!"ReturnEndifLocal _tree := New TreeView_tree.RootNode.Text = "XML document"AddXMLNodeToTree(doc, _tree.RootNode)ContentView = _treedoc.Destroy()EndMethod AddXMLNodeToTree(xmlNode:XMLNode, parent:TreeView.Node)Local str := ""Local xmlElement := xmlNode.ToElement()If xmlElementstr += "<" + xmlNode.Value()Local attrib := xmlElement.FirstAttribute()While attribstr += " " + attrib.Name() + "=~q" + attrib.Value() + "~q "attrib=attrib.NextAttribute()wendstr += ">"Elsestr += xmlNode.Value()EndifLocal treeNode:TreeView.NodeIf strtreeNode = New TreeView.Node(str, parent)EndifLocal xmlChild := xmlNode.FirstChild()While xmlChildIf Not xmlChild.NoChildren()If treeNode Then parent = treeNodeEndifAddXMLNodeToTree(xmlChild, parent)xmlChild = xmlChild.NextSibling()WendEndEndFunction LoadEmbeddedXMLString:string()Local str := "<?xml version=~q1.0~q encoding=~qUTF-8~q?><recipes><recipe><name>Recall Scroll</name><results><item name=~qRecall Scroll~q quantity=~q1~q /></results><requirements><skill name=~qAlchemy~q level=~q0~q /><item name=~qMortar and Pestle~q quantity=~q1~q /><item name=~qWood Pulp~q quantity=~q5~q /><item name=~qNightshade~q quantity=~q10~q /><item name=~qBlack Pearl~q quantity=~q10~q /></requirements></recipe><recipe><name>Teleport Scroll</name><results><item name=~qTeleport Scroll~q quantity=~q1~q /></results><requirements><skill name=~qAlchemy~q level=~q0~q /><item name=~qMortar and Pestle~q quantity=~q1~q /><item name=~qWood Pulp~q quantity=~q5~q /><item name=~qMandrake Root~q quantity=~q10~q /><item name=~qBlack Pearl~q quantity=~q10~q /></requirements></recipe></recipes>"Return strEndSeptember 17, 2016 at 7:03 pm #3989The module builds but I’m getting pretty much empty .cpp source files in my windows_debug folder and if I try to use any of the extension methods I get “undefined reference” errors.
Are you using the latest mx2cc? Extensions are undergoing ongoing maintenance…
If you are, can you reproduce with a simple example?
September 18, 2016 at 9:15 am #3994Actually, it looks like I’m not on the latest version. I’ll update later and give it a try.
September 18, 2016 at 8:27 pm #4006Extension methods fail to build at all with the latest code, whether as a module or not.
Lots of “Blah:T?(T?) must be a generic class type” errors.
The code built fine in v1.0.5
Have attached if you want to have a look.
Attachments:
September 18, 2016 at 8:41 pm #4009Also, the following no longer works in the latest build either:
Monkey1234567891011121314Namespace test#Import "<std>"Using std..Function Main()Print(Int(TestGenericMethod<Int>()))EndFunction TestGenericMethod<T>:Bool() Where T Implements INumericReturn TrueEndGet error: Can’t find overload for ‘TestGenericMethod<int>(…)’ with argument types ()
Again, this used to work in v1.0.5, and works in 1.0.6 if I remove the Where clause
September 18, 2016 at 10:39 pm #4010Have you got a small test program for the Linq stuff?
 - 
		AuthorPosts
 
You must be logged in to reply to this topic.