Example on reading/writing xml file?

General help with the eC language.
Post Reply
samsam598
Posts: 212
Joined: Thu Apr 14, 2011 9:44 pm

Example on reading/writing xml file?

Post by samsam598 »

Greetings,

Is there any example code that reading from a xml file to the console and writing back?

Thanks for the help in advance.

Regards,
Sam
jerome
Site Admin
Posts: 608
Joined: Sat Jan 16, 2010 11:16 pm

Re: Example on reading/writing xml file?

Post by jerome »

Hi Sam! Sorry for the late replies...

About XML, the only thing we have in the SDK is under sdk/extras/XMLParser. It is a very simple XML parser.

To use it, you basically derive a class from the XMLParser class, and override its two methods. Then you instantiate your derived class and invoke the Parse method with a string containing the XML text data to parse and its length. The two methods to override are:
  • ProcessKeyword: invoked when a tag marker is read
  • ProcessCharacterData: invoked when text data is read
Here is a sample of what it looks like:

Code: Select all

import "ecere"
import "XMLParser"
 
define app = (XMLReadApp)__thisModule.application;
 
class ConsoleParser : XMLParser
{
   void ProcessKeyword(char * keyWord)
   {
      // keyWord first holds the tag name
      if(closingTag)
         // The parser will come here for closing tags and for self-closing tags (e.g. <tag /> or <?xml ?>)
         Print(openingTag ? "<" : "</", keyWord);
      else
         // Otherwise the parser will come here for an opening tag
         Print("<", keyWord);
 
      // Note: the current tag depth is in the xmlDepth data member
 
      // This loops through any tag attribute
      while(GetWord())
      {
         // After invoking GetWord(), keyWord now holds the attribute name
 
         // This prints a space before the attribute name
         if(strcmp(keyWord, "?")) Print(" ");
 
         // This prints the attribute name...
         Print(keyWord);
 
         // After invoking GetWord(), keyWord will now hold the attribute value which we'll print within quotes
         if(GetWord())
            Print("=\"", keyWord, "\"");
      }
      Print(">");
   }
 
   void ProcessCharacterData(char * data)
   {
      // The parser will come here for data (stuff not inside tags)
      // This will include characters (including spaces) both within inner and outer tags
      // Further processing could be done here...
      Print(data);
   }
}
 
class XMLReadApp : Application
{
   void Main()
   {
      if(argc > 1)
      {
         File f = FileOpen(argv[1], read);
         if(f)
         {
            ConsoleParser parser { };
            uint size = f.GetSize();
            byte * buffer = new byte[size];
            f.Read(buffer, 1, size);
 
            // For XML files that are UTF-16 encoded with a BOM, this will handle the little endian UTF-16
            if(buffer[0] == 0xFF && buffer[1] == 0xFE)
            {
               char * newBuffer = UTF16toUTF8(buffer+2);
               delete buffer;
               buffer = newBuffer;
               size = strlen(newBuffer);
            }
            parser.Parse(buffer, size);
            delete f;
            delete parser;
         }
      }
      system("pause");
   }
}
You can find also an example usage of the XMLParser for handling data sent through network sockets under sdk/samples/net/XMLSample.

Alternatively, libexpat is a decent open source C library for dealing with XML files, which you should be able to use in conjunction with Ecere/eC without too much trouble :)

Additionally, Ecere provides a class to parse and save JSON (Java Script Object Notation) data. I personally prefer by far JSON over XML, and JSON is what is used for the new Ecere project file format (.epj). It is also used by the newest IDE configuration settings and is an option for the GlobalAppSettings class.

The JSON parser is used by defining a class which essentially describes the schema of the data. The class can contain eC containers (specifying the elements data type, e.g. Array<int>) to organize the hierarchy of the data. Then the parser will automatically store the data being parsed in an instance of such a class, and can write back the data from the instance.

This sounds a bit like what you are trying to do, right? It would be possible (and interesting) to make this work with XML as well, maybe with some code from the JSONParser class on top of the XMLParser. But I still prefer JSON as the data format is more compact and readable :)

Hope this helps :) Please let me know if you have further questions about these tools.

Best regards,

Jerome
Attachments
xmlRead.ec
(2.13 KiB) Downloaded 2749 times
jerome
Site Admin
Posts: 608
Joined: Sat Jan 16, 2010 11:16 pm

Re: Example on reading/writing xml file?

Post by jerome »

Added Note: you might find useful to keep flag(s) saying whether you're inside a particular tag (you set the flag in ProcessKeyword).

Then you can check this flag within ProcessCharacterData, and you only care about the data for tags actually meant to contain character data (higher level tags container other tags usually don't)...

Some types of XML files might describe everything as tags and do not use character data at all...

JSON doesn't suffer from this confusion... Everything is a very specific data type, no character data unless you are within an attribute! Take a look at http://www.json.org/xml.html

XML is awful, truly!
Post Reply