Selaa lähdekoodia

XML Document element traversal

Allows traversing an xml document by element without needing to know the element name
Blind traversal allows more dynamic loading of xml docs and logic to wrap different outcomes

new script functions:
prevElement
nextElement
nextChildElement

<main> <--- we are here
  <child> <-- nextChildElement will take us here
  </child>
  <child2> <-- after nextChildElement nextElement will take us here
  </child2>
</main>
<main2> <-- next element will bring us here
</main2>
marauder2k7 1 kuukausi sitten
vanhempi
sitoutus
c53d79a8cf
2 muutettua tiedostoa jossa 101 lisäystä ja 0 poistoa
  1. 95 0
      Engine/source/console/SimXMLDocument.cpp
  2. 6 0
      Engine/source/console/SimXMLDocument.h

+ 95 - 0
Engine/source/console/SimXMLDocument.cpp

@@ -1419,4 +1419,99 @@ DefineEngineMethod( SimXMLDocument, getData, const char*, (),,
    return text;
 }
 
+bool SimXMLDocument::prevElement()
+{
+   m_CurrentAttribute = NULL;
+
+   if (m_paNode.empty())
+      return false;
+
+   S32 idx = m_paNode.size() - 1;
+   tinyxml2::XMLNode*& curr = m_paNode[idx];
+
+   if (!curr)
+      return false;
+
+   tinyxml2::XMLNode* prev = curr->PreviousSiblingElement();
+
+   if (!prev)
+      return false;
+
+   curr = prev;
+   return true;
+}
+
+DefineEngineMethod(SimXMLDocument, prevElement, const char*, (), ,
+   "@brief Move to previous sibling element regardless of name.\n"
+   "@return The element name, or empty string if none.\n")
+{
+   if (object->prevElement())
+      return object->elementValue();
+
+   return "";
+}
+
+bool SimXMLDocument::nextElement()
+{
+   m_CurrentAttribute = NULL;
+
+   if (m_paNode.empty())
+      return false;
+
+   S32 idx = m_paNode.size() - 1;
+   tinyxml2::XMLNode*& curr = m_paNode[idx];
+
+   if (!curr)
+      return false;
+
+   tinyxml2::XMLNode* next = curr->NextSiblingElement();
+
+   if (!next)
+      return false;
+
+   curr = next;
+   return true;
+}
+
+DefineEngineMethod(SimXMLDocument, nextElement, const char*, (), ,
+   "@brief Move to next sibling element regardless of name.\n"
+   "@return The element name, or empty string if none.\n")
+{
+   if (object->nextElement())
+      return object->elementValue(); // return the name of the element
+
+   return "";
+}
+
+bool SimXMLDocument::nextChildElement()
+{
+   m_CurrentAttribute = NULL;
+
+   if (m_paNode.empty())
+      return false;
+
+   tinyxml2::XMLNode* parent = m_paNode.back();
+   if (!parent)
+      return false;
+
+   tinyxml2::XMLElement* firstChild = parent->FirstChildElement();
+   if (!firstChild)
+      return false;
+
+   m_paNode.push_back(firstChild);
+   return true;
+}
+
+DefineEngineMethod(SimXMLDocument, nextChildElement, const char*, (),,
+    "@brief Move to the next child element under the same parent.\n"
+    "@return True if a next child exists, false otherwise.")
+{
+   if (object->nextChildElement())
+   {
+      const char* name = object->elementValue();
+      return name ? name : "";
+   }
+   return "";
+}
+
 ////EOF/////////////////////////////////////////////////////////////////////////

+ 6 - 0
Engine/source/console/SimXMLDocument.h

@@ -132,6 +132,12 @@ class SimXMLDocument: public SimObject
       void addData(const char* text);
       // Retrieve data from the current level.
       const char* getData();
+
+      bool prevElement();
+
+      bool nextElement();
+
+      bool nextChildElement();
       
    private:
       // Document.