Reading XML files
BlitzMax Forums/BlitzMax Programming/Reading XML files
| ||
Hi, I have started trying to use Brucey's libxml module, but I'm having trouble getting it to do what I want. I have an XML file like the one below. I want to read it and create objects based on the type of node. Any 'type2' object can have a list of objects within it. It's for a level editor where 'type2' is an event with a list of commands to execute if the event is triggered. <main> <type1/> <type2> <type1/> <type1/> <type2> <type1/> <type2> <type1/> </type2> <type1/> </type2> </type2> </main> Can anyone give me any tips? Thank you. |
| ||
'load and parse file local xmlFile:TxmlDoc = TxmlDoc.parseFile("myfile.xml") '<main> local rootNode:TXmlNode = xmlFile.getRootElement() if not rootNode then Throw "<main> not found" local subElements:TList = rootNode.GetChildren(XML_ELEMENT_NODE) if not subElements then Throw "no children below <main>" For local node:TXmlNode = EachIn subElements Select node.GetName().tolower() Case "type2" 'do whatever is needed Case "type3" 'do ba di ba doo default print "found unhandled node of kind ~q"+node.GetName()+"~q" End Select Next Above's code is untested, but should help to know how to handle xml content. As LibXML returns null values if it does not find elements, you always need to ensure that the result is valid before using it ("For local node:TXmlNode = EachIn rootNode.GetChildren(XML_ELEMENT_NODE)" might segfault - if no children are present). Therefor I created a little XML helper in my framework: https://github.com/GWRon/Dig/blob/master/base.util.xmlhelper.bmx Maybe you could "steal" some convenience functions from it to make life easier with libXML. bye Ron |
| ||
Hi Derron, Thank you for the example. What I'm really struggling with is loading an unknown amount of nested child nodes. I would show my code, but it's horrible and clearly shows I don't know what I'm doing. I know it needs some kind of recursive function, but I can't wrap my head around it. :/ |
| ||
You may find the TxmlTextReader API is useful. There's a small example of it in test/test2.bmx There's documentation on it here : http://www.xmlsoft.org/xmlreader.html Although the docs are not specific to BlitzMax, the API should be essentially the same, and the descriptions on extracting information from nodes/attributes should translate across to the module. |
| ||
Just wrap the corresponding for-eachin-loop into a function and call it recursively:Function LoadSubElements(subElements:TList) if not subElements then return For local node:TXmlNode = EachIn subElements Select node.GetName().tolower() Case "type2" LoadType2Element(node) Case "type3" 'do ba di ba doo default print "found unhandled node of kind ~q"+node.GetName()+"~q" End Select Next End Function Function LoadType2Element(node:TXmlNode) 'do custom stuff (loading special type2-nodes) 'load other types contained in that type2 LoadSubElements(node) End Function Above is just one way to do that. bye Ron |
| ||
Here's a small example using the xmlTextReader API in NG... some_stuff.xml contains your xml example from above. The output looks like: Main Type1 Type2 Type1 Type1 Type2 Type1 Type2 Type1 Type1 It is non-recursive, using a stack to track parent nodes. A node factory manages node creation. This particular example uses NG's interfaces, but it is easy enough to write it without. |
| ||
@reader Seems a bit more complex than needed for the OP. Nonetheless nice to see another sample for NG's interfaces. bye Ron |
| ||
@Reader I've updated the example to make type1 a standard node and type2 a container type. It will now throw an exception if you try to add a node to a non-container node. As for complex, I don't think it is. Most of the example code comprises the type stuff at the end - in order to make the example complete. The reader-specific stuff is in the while loop, and most of that is code to handle the stack. Sure, you could call something recursively if you really wanted, but this example shows that you don't need to if you don't want to :-) |
| ||
Thank you both! I think I have gotten it working how I want to. |