Effective way to load an XML File

Post Reply
Javi
Posts: 29
Joined: Sat Jun 11, 2022 5:14 am
Been thanked: 10 times

Effective way to load an XML File

Post by Javi »

Example

persons.xml

Code: Select all

<?xml version="1.0" encoding="UTF-8"?>
<persons>
	<person name="John" >
   	<properties>
  	  	<property name="age" value="30"/>
    	<property name="gender" value="man"/>
		<property name="profession" value="dentist" />
     </properties>
  </person>
  <person name="Mary" >
   	<properties>
	 	<property name="age" value="31"/>
    	<property name="gender" value="woman"/>
		<property name="profession" value="engineer" />
     </properties>
	</person>	
</persons>

The loader code. The complex part. Not necessary to understand it at full. Just use it.

XML_Loader.pi

Code: Select all

//-----------------------------------------------------------------------------
// XML_Loader Script
// based on 
// TMX_Loader by Alberto De Hoyo Nebot
// VR-Script modifications: Javi
//-----------------------------------------------------------------------------


class XML_Loader
{

	class Object
	{
		properties:
			name = "";
			type = "";
			subList = [];
			
		function _operator_delete ()
		{
			for (i=0; i<sizeof(subList); i++)
			{	
				_list = _get(subList[i]);
				for (j=0; j<sizeof(_list); j++)
					delete _list[j];
			}
			subList = [];
		}
	};
	
	
	properties:
	
		TAG_NAME_LIST = "list";
		TAG_NAME_TEXT = "text";
	
		xmlDoc = null;
		xmlElement = null;
		subList = [];
		
	function _operator_new ()
	{
	}
		
	function _operator_delete ()
	{
		for (i=0; i<sizeof(subList); i++)
		{	
			_list = _get(subList[i]);
			for (j=0; j<sizeof(_list); j++)
				delete _list[j];
		}
		subList = [];
	}
	
	function LoadStartFromFile (_file)
	{
		_fileSize = File_Size(_file);
		_buffer = Buffer_New (_fileSize);
		File_Read (_file, _buffer, 0, _fileSize);
		File_Close (_file);
		_xmlStr = Buffer_GetString (_buffer, 0);
		Buffer_Delete (_buffer);
		
		xmlDoc = XML_Open (_xmlStr);
		if (!xmlDoc)
		{
			return 0;
		}
		
		xmlElement = XML_GetRootElement (xmlDoc);

		_num_steps = GetNumSteps (xmlElement);
				
		return _num_steps;
	}
	
	function LoadStart (_filename)
	{
		_file = File_Open (_filename, FILE_MODE_READ);
		if (!_file)
		{
			return false;
		}
		return LoadStartFromFile (_file);
	}

	function LoadXML(_filename)
	{
		if (!LoadStart (_filename))
			return false;
		ReadClass (this, xmlElement);
		XML_Close (xmlDoc);
		return true;
	}

	function LoadNext ()
	{
		if (!xmlElement) return false;
		_xmlElement = ReadClass (this, xmlElement, true);
		xmlElement = _xmlElement;
		if (!xmlElement)
		{
			XML_Close (xmlDoc);
			return false;
		}
		return true;
	}

	function GetNumSteps (_e)
	{
		_count = 0;
		while (_e)
		{
			_e = XML_NextElement (_e);
			_count++;
		}
		return _count;
	}

	function ReadClass (_obj, _e, _iterative = false)
	{
		while (_e)
		{
			_key = XML_GetElementName (_e);
			_text = XML_GetElementValue (_e);
		
			_class = new Object();
			
			ReadAttributes (_class, _e);
			ReadClass (_class, XML_GetRootElement (_e));

			if (_obj._implements(_key + TAG_NAME_LIST))
			{
				_list = _obj._get(_key + TAG_NAME_LIST);
			}
			else
			{
				_list = [];
				_obj.subList += [_key + TAG_NAME_LIST];
			}
			_list += [_class];
			_obj._set(_key + TAG_NAME_LIST, _list);
			_obj._set(_key + TAG_NAME_TEXT, _text);
			
			_e = XML_NextElement (_e);
			if (_iterative) break;
		}
		
		return _e;
	}

	function ReadAttributes (_obj, _e)
	{
		_a = XML_FirstAttribute (_e);
		while (_a)
		{
			_name = XML_GetAttributeName (_a);
			_value = XML_GetAttributeValue (_a);
			_obj._set (_name, _value);
			_a = XML_NextAttribute (_a);
		}
	}
	
	
	function Load(_engine, _path, _actorCreator = null)
	{
	
		_xml = LoadXML(_engine.GetPath(_path));
		if (!_xml) return false;
		
		
		if (_actorCreator && _actorCreator._implements("AddActor") ) 
		{
			_process = _actorCreator.AddActor( _engine.GetDOS(true).GetConsole(), this);
			if (!_process) return false;
		}
		
		return true;
		
	}
		
		
}

Example 1 with VR-DOS

test.pi

Code: Select all

//-----------------------------------------------------------------------------
// XMLTest Script
// based on
// TMX_Loader by Alberto De Hoyo Nebot
// VR-Script modifications: Javi
//-----------------------------------------------------------------------------


class XMLTest implements DOS_Program
{

	
	virtual Start()
	{
        
		
		xml_loader = new XML_Loader();
		_ok = xml_loader.Load(GetEngine(), "persons.xml", this);

		delete xml_loader;
		End(0);
	
		::Start();
	}
	

	function AddActor(console, _data)
	{
	
			_persons = _data.personsList[0];
			
			for (i=0; i<sizeof(_persons.personList); i++)
			{
					_person = _persons.personList[i];

					console.PrintLn("person name = " +  _person.name);
					

					if (_person._implements("propertiesList"))
					{
						_params = [];

						for (k=0; k<sizeof(_person.propertiesList[0].propertyList); k++)
						{
									_prop = _person.propertiesList[0].propertyList[k];
									_params += [[ _prop.name, _prop.value ]];

									console.PrintLn( _prop.name + " = " + _prop.value);
						}
	
					}
					
 	
					console.PrintLn("");
	
			}
		
			
			console.Input("", null, 1);
			return true;

	}
	
	
}


Example 2 with VRSCRIPT and using a Dictionary

main.pi

Code: Select all

//-----------------------------------------------------------------------------
// XMLTest Script
// based on
// TMX_Loader by Alberto De Hoyo Nebot
// VR-Script modifications: Javi
//-----------------------------------------------------------------------------


class XMLTest implements GL_Program
{

	properties:
	
		players = [];  //List of players
		
		

	function Start()
	{
		xml_loader = new XML_Loader();
		_ok = xml_loader.Load(GetEngine(), "persons.xml", this);

		delete xml_loader;
	
		End(0);
	
		::Start();
	}

	function AddActor(console,  _data)
	{
	
			_persons = _data.personsList[0];
			
			for (i=0; i<sizeof(_persons.personList); i++)
			{
					_person = _persons.personList[i];


					if (_person._implements("propertiesList"))
					{
						_params = [[ "name", _person.name ]];

						for (k=0; k<sizeof(_person.propertiesList[0].propertyList); k++)
						{
									_prop = _person.propertiesList[0].propertyList[k];
									_params += [[ _prop.name, _prop.value ]];
									
					
						}
	
						players += [[ string(i), _params]];
	
					
					}
					
	
			}


			for (i=0; i<sizeof(players); i++)
			{
				console.PrintLn("person name = " +  players [string(i) ] ["name"]);
				console.PrintLn("age = " 		 +  players [string(i) ] ["age"]);
				console.PrintLn("gender = " 	 +  players [string(i) ] ["gender"]);
				console.PrintLn("profession = "  +  players [string(i) ] ["profession"]);
				console.PrintLn("");
			}



			console.Input("", null, 1);
			return true;

	}
	
}

code included to download it as a zip file.
Attachments
xml.zip
(3.15 KiB) Downloaded 1 time
Post Reply