Game Development Community

XML read for T3D

by Scott Peal · in Torque 3D Professional · 08/26/2009 (9:01 pm) · 11 replies

I have searched all of the forums and found TGE examples for XML and I cannot get them to work. I noticed that TinyXML was included in the source and I found a help HTML for it here: D:TorqueTorque 3D 2009 Beta 5Enginelibtinyxmldocstutorial0.html

My question is, do we use it in script with the commands from the help HTML or are there script specific commands? Does anyone have a pointer to how to pull and XML file in and parse it via script in T3D?

Much appreciated.

[edit]
I extracted the following commands from SimXMLDocument.cs file. Hope this helps others.

SimXMLDocument.parse - "Create document from XML string."
SimXMLDocument.clear - "Clear contents of XML document."
SimXMLDocument.getErrorDesc - "Get current error description."
SimXMLDocument.clearError - "Clear error description."
SimXMLDocument.pushFirstChildElement - "Push first child element with given name onto stack."
SimXMLDocument.pushChildElement - "Push the child element at the given index onto stack."
SimXMLDocument.nextSiblingElement - "Set top element on stack to next element with given name."
SimXMLDocument.elementValue - "Get element value if it exists (string)."
SimXMLDocument.popElement - "Pop last element off of stack."
SimXMLDocument.attribute - "Get attribute value if it exists (string)."
SimXMLDocument.attributeF32 - "Get attribute value if it exists (float)."
SimXMLDocument.attributeS32 - "Get attribute value if it exists (int)."
SimXMLDocument.attributeExists - "Get true if named attribute exists."
SimXMLDocument.firstAttribute - "Obtain the name of the current element's first attribute."
SimXMLDocument.lastAttribute - "Obtain the name of the current element's last attribute."
SimXMLDocument.nextAttribute - "Get the name of the next attribute for the current element after a call to firstAttribute()."
SimXMLDocument.prevAttribute - "Get the name of the previous attribute for the current element after a call to lastAttribute()."
SimXMLDocument.setAttribute - "Set attribute of top stack element to given value."
SimXMLDocument.setObjectAttributes - "Set attribute of top stack element to given value."
SimXMLDocument.pushNewElement - "Create new element as child of current stack element and push new element on to stack."
SimXMLDocument.addNewElement - "Create new element as child of current stack element and push new element on to stack."
SimXMLDocument.addHeader - "Add XML header to document."
SimXMLDocument.addComment - "Add the given comment as a child of current stack element."
SimXMLDocument.readComment - "Returns the comment at the specified index."
SimXMLDocument.addText - "Add the given text as a child of current stack element."
SimXMLDocument.getText - "Gets the text from the current stack element."
SimXMLDocument.removeText - "Remove any text on the current stack element."
SimXMLDocument.addData - "Add the given text as a child of current stack element."
SimXMLDocument.getData - "Gets the text from the current stack element."

#1
08/26/2009 (10:25 pm)
I figured it out thanks to another thread on the subject. Sorry I lost the thread and name of the original author. But he rocks! Here is my version of the code:

function getModelsInCatagory()
{ 
   %file = "./Catalog.xml";
   %fo = new FileObject();
   %text = "";

   if(%fo.openForRead(%file))
   {
      while(!%fo.isEOF())
      {
         %text = %text @ %fo.readLine();
         if (!%fo.isEOF()) %text = %text @ "n";
      }
   }
   else
   {
      echo("Unable to locate the file: " @ %file);
   }

   %fo.delete();
   
   %xml = new SimXMLDocument() {};   
   %xml.parse(%text);   
  
   // "Get" inside of the root element, "Students".   
   %xml.pushChildElement(0);   
  
   // "Get" into the first child element    
   if (%xml.pushFirstChildElement("Model"))   
   {   
      while (true)   
      {   
         /*   
         * Here, i read the element's attributes.   
         * You might want to save these values in an array or call the %xml.getElementValue()  
         * if you have a different XML structure.  
         */  
         %catagory = %xml.attribute("catagory");   
         %name = %xml.attribute("name");   
         %path = %xml.attribute("path");   
         
         // now, read the next "Model"   
         if (!%xml.nextSiblingElement("Model")) break;    
      }   
   }
}
#2
08/31/2009 (2:19 am)
Is this functionality not already in T3d ?

Has this been tested with Beta 5 ?
#3
08/31/2009 (10:09 am)
It's been there since day 1. It came from TGEA actually.
#4
08/31/2009 (5:28 pm)
My code above is working in Beta5 and is working great. The only thing I could not figure out is that there is a %xml.LoadFile() function and I was not able to figure out how to get it to work.
#5
09/02/2009 (1:04 am)
Ok that explains alot . I could not get xml.LoadFile() to work either .
#6
09/02/2009 (5:42 am)
you would actually open a file and read it from start to end into a string and then send that string to the Parse function
#7
09/03/2009 (4:44 pm)
@Marc: The question is how to leverage the %xml.LoadFile() function instead. Do you have an example using that function you can share with us?
#8
10/09/2009 (6:46 pm)
I tried getting xml.loadFile() to work and it didn't...
until I wrote a valid xml file back out and included the header.

When you use the nodes to create an xml file, make sure to call %xml.addHeader(); This adds the following line to the top of the file:

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>

This makes for a "valid" xml file. Once that line was in the file, I was able to use .loadFile() without any trouble.
#9
10/10/2009 (10:28 am)
@Rex: That's good info. Any chance you can post an example of how you loaded the file? I was not able to get it to work with a properly formated XML file. Thanks a heap in advance.
#10
10/12/2009 (10:54 am)
Given:

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<DataTables>
    <table tableName="2DShapes">
        <rec id="1">Triangle</rec>
        <rec id="2">Square</rec>
        <rec id="3">Circle</rec>
    </table>
    <table tableName="3DShapes">
        <rec id="1">Pyramid</rec>
        <rec id="2">Cube</rec>
        <rec id="3">Sphere</rec>
    </table>
</DataTables>

This is the code used to read it:
function readXmlExample(%filename)
{
   %xml = new SimXMLDocument() {};
   %xml.loadFile(%filename);
   
   %xml.pushChildElement("DataTables");
   %xml.pushFirstChildElement("table");
   while(true)
   {
      echo("TABLE:" SPC %xml.attribute("tableName"));
      %xml.pushFirstChildElement("rec");
      while (true)
      {
         %id = %xml.attribute("id");
         %desc = %xml.getData();
         echo("  Shape" SPC %id SPC %desc);
         if (!%xml.nextSiblingElement("rec")) break;
      }
      %xml.popElement();
      if (!%xml.nextSiblingElement("table")) break;
   }
}
#11
10/12/2009 (1:55 pm)
Thanks Rex! I hope we can return the favor one day.