Author Topic: ScriptBasic Mini-XML Extension Module  (Read 25587 times)

Support

  • Administrator
  • *****
  • Posts: 19
    • View Profile
ScriptBasic Mini-XML Extension Module
« on: April 10, 2011, 05:45:16 PM »
Mini-XML is a small XML library that you can use to read and write XML and XML-like data files in your application without requiring large non-standard libraries.

Armando created the mxml extension module as a replacement for the GNOME libxml2 extension module that was introduced with the 2.0 release by Peter Verhas but never fully tested or documented.

Code: [Select]
include mxml.bas

filename = "stuff.xml"
doc = mxml::LoadDoc(filename)

node =  mxml::GetNode(doc,"/stufflist/stuff_test")
if node then print "Test1: ", mxml::GetNodeValue(node),"\n"
node =  mxml::GetNode(doc,"/stufflist/stuff_test2")
if (node) then print "Test2: ", mxml::GetNodeValue(node),"\n\n"

node = mxml::GetNode(doc,"/stufflist/stuff_test3/painting/img")
if node then
print "Image: ", mxml::GetProperty(node,"src"), "\n"
print "Alt Image: ", mxml::GetProperty(node,"alt"), "\n\n"
endif

node = mxml::GetNode(doc,"/stufflist/books")
child = mxml::GetChild(node)

while child
node = mxml::GetNode(child,"id")
if node then print "ID = ", mxml::GetNodeValue(node),"\n"
node = mxml::GetNode(child,"name")
if node then print "Name = ", mxml::GetNodeValue(node),"\n"
child = mxml::GetNext(child)
wend

if doc then mxml::FreeDoc(doc)

Code: Text
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <stufflist>
  3.         <stuff_test>This is a test!</stuff_test>
  4.         <stuff_test2>And this is another test!</stuff_test2>
  5.         <stuff_test3>
  6.                 <painting>
  7.                         <img src="madonna.jpg" alt='Foligno Madonna, by Raphael'/>
  8.                         <caption>This is Raphael's "Foligno" Madonna, painted in
  9.                                 <date>1511</date>.
  10.                         </caption>
  11.                 </painting>
  12.         </stuff_test3>
  13.         <books>
  14.     <book>
  15.         <id>1</id>
  16.         <name>Hello, world!</name>
  17.     </book>
  18.     <book>
  19.         <id>2</id>
  20.         <name>Hello, China!</name>
  21.     </book>
  22.         </books>
  23. </stufflist>
  24.  

jrs@Laptop:~/SB/test$ scriba mxmltest.sb
Test1: This is a test!
Test2: And this is another test!

Image: madonna.jpg
Alt Image: Foligno Madonna, by Raphael

ID = 1
Name = Hello, world!
ID = 2
Name = Hello, China!
jrs@Laptop:~/SB/test$


The attached mxml_i386.tar.gz is for 32 bit versions of Linux.

Support

  • Administrator
  • *****
  • Posts: 19
    • View Profile
Re: ScriptBasic Mini-XML Extension Module
« Reply #1 on: April 13, 2011, 01:14:59 PM »
The Mini-XML API isn't fully implemented in the ScriptBasic mxml extension module. If you find this interface of value and would be willing to contribute by expanding it, please reply here and indicate your willingness to help the project out.


Mini-XML API
mxmlAdd
mxmlDelete
mxmlElementDeleteAttr
mxmlElementGetAttr
mxmlElementSetAttr
mxmlElementSetAttrf
mxmlEntityAddCallback
mxmlEntityGetName
mxmlEntityGetValue
mxmlEntityRemoveCallback
mxmlFindElement
mxmlIndexDelete
mxmlIndexEnum
mxmlIndexFind
mxmlIndexNew
mxmlIndexReset
mxmlLoadFd
mxmlLoadFile
mxmlLoadString
mxmlNewCDATA
mxmlNewCustom
mxmlNewElement
mxmlNewInteger
mxmlNewOpaque
mxmlNewReal
mxmlNewText
mxmlNewTextf
mxmlNewXML
mxmlRelease
mxmlRemove
mxmlRetain
mxmlSAXLoadFd
mxmlSAXLoadFile
mxmlSAXLoadString
mxmlSaveAllocString
mxmlSaveFd
mxmlSaveFile
mxmlSaveString
mxmlSetCDATA
mxmlSetCustom
mxmlSetCustomHandlers
mxmlSetElement
mxmlSetErrorCallback
mxmlSetInteger
mxmlSetOpaque
mxmlSetReal
mxmlSetText
mxmlSetTextf
mxmlSetWrapMargin
mxmlWalkNext
mxmlWalkPrev

ScriptBasic extension module interface
declare sub     ::LoadDoc      alias "LoadDoc"      lib "mxml"
declare sub     ::GetNext      alias "GetNext"      lib "mxml"
declare sub     ::GetChild     alias "GetChild"     lib "mxml"
declare sub     ::GetNodeValue alias "GetNodeValue" lib "mxml"
declare sub     ::GetProperty  alias "GetProperty"  lib "mxml"
declare sub     ::GetNode      alias "GetNode"      lib "mxml"
declare sub     ::SaveDoc      alias "SaveDoc"      lib "mxml"
declare sub     ::NewDoc       alias "NewDoc"       lib "mxml"
declare sub     ::FreeDoc      alias "FreeDoc"      lib "mxml"

Mini-XML functions used by ScriptBasic
mxmlLoadFile
mxmlElementGetAttr
mxmlFindElement
mxmlSaveFile
mxmlNewXML
mxmlDelete

mxml ScriptBasic interface.c
Code: [Select]
/*

Mini-XML Support code for Scriptbasic

Copyright 2010, Armando I. Rivera, Recursive Media Group.

Released under the terms of the Mini-Xml Licence.

The Mini-XML library and included programs are provided under the terms of the
GNU Library General Public License (LGPL) with the following exceptions:

  1. Static linking of applications to the Mini-XML library does not constitute
a derivative work and does not require the author to provide source code for
the application, use the shared Mini-XML libraries, or link their applications
against a user-supplied version of Mini-XML.

  If you link the application to a modified version of Mini-XML, then the
changes to Mini-XML must be provided under the terms of the LGPL in sections
1, 2, and 4.

  2. You do not have to provide a copy of the Mini-XML license with programs
that are linked to the Mini-XML library, nor do you have to identify the
Mini-XML license in your program or documentation as required by section 6
of the LGPL.

  FILE   : interface.c
  HEADER : interface.h
  BAS    : mxml.bas
  AUTHOR : *TODO*

  DATE:

  CONTENT:
  This is the interface.c file for the ScriptBasic module xml

UXLIBS: -lmxml
DWLIBS: -lmxml

 */

#include <mxml.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "../../basext.h"

typedef struct _ModuleObject {
  void *HandleArray;
}ModuleObject,*pModuleObject;

#define _MAX_PATH 4096

#define GET_ARGUMENT_POINTER(X,Y) \
  if( besARGNR < Y )return COMMAND_ERROR_ARGUMENT_RANGE;\
  Argument = besARGUMENT(Y);\
  besDEREFERENCE(Argument);\
  if( Argument == NULL )X=NULL; else { \
      if( Argument->vType != VTYPE_STRING ||\
          STRLEN(Argument) != sizeof(void *) ){\
    return COMMAND_ERROR_ARGUMENT_RANGE;\
    }\
  memcpy(&(X),STRINGVALUE(Argument),sizeof(void *));\
  }

#define RETURN_POINTER(X) \
  besALLOC_RETURN_STRING( sizeof( void *) );\
  memcpy(STRINGVALUE(besRETURNVALUE),&(X),sizeof(void *));



besVERSION_NEGOTIATE
  return (int)INTERFACE_VERSION;
besEND

besSUB_START
  pModuleObject p;

  besMODULEPOINTER = besALLOC(sizeof(ModuleObject));
  if( besMODULEPOINTER == NULL )return 0;

  p = (pModuleObject)besMODULEPOINTER;
  return 0;

besEND

besSUB_FINISH
  pModuleObject p;

  p = (pModuleObject)besMODULEPOINTER;
  if( p == NULL )return 0;
  return 0;
besEND

/**
=section LoadDoc
=H Load an XML file and read into memory

You should use this function to read the content of an XML file into memory.
The argument of the function is the name of the file to be read. The function
will return a handle to the structure created during the parsing of the file
content.

=verbatim
 DOC = mxml::LoadDoc("my_file.xml")
=noverbatim

*/
besFUNCTION(LoadDoc)
mxml_node_t *tree;
FILE *fp;
char *pszFileName;

besARGUMENTS("z")
    &pszFileName
  besARGEND

fp = fopen(pszFileName, "r");
  // check if file exists
  if(fp == NULL) {
      return NULL;
  }
   
  tree = mxmlLoadFile(NULL, fp, MXML_OPAQUE_CALLBACK);
fclose(fp);

  //besFREE(pszFileName);

  besRETURN_POINTER(tree);
besEND

/**
=section GetNext
=H Get the next node of a document node

This function should be used to get the handle to the  next node in a
document node

=verbatim
 node = mxml::GetNext(<node pointer>)
=noverbatim
*/
besFUNCTION(GetNext)
mxml_node_t *rootNode;

besARGUMENTS("p")
    &rootNode
  besARGEND

besRETURN_POINTER(rootNode->next);
besEND

/**
=section GetChild
=H Get the next Child node of a document node

This function should be used to get the handle to the next Childe node of a
document node

=verbatim
 node = mxml::GetChild(<node pointer>)
=noverbatim
*/
besFUNCTION(GetChild)
mxml_node_t *rootNode;

besARGUMENTS("p")
    &rootNode
  besARGEND

besRETURN_POINTER(rootNode->child);
besEND

/**
=section GetNodeValue
=H Get the value of a document node

This function should be used to get the value (text) of a node

=verbatim
 text = mxml::GetNodeValue(<node pointer>)
=noverbatim
*/
besFUNCTION(GetNodeValue)
mxml_node_t *rootNode;

besARGUMENTS("p")
    &rootNode
  besARGEND

besSET_RETURN_STRING(rootNode->child->value.opaque);
besEND

/**
=section GetProperty
=H Get the a property value of a document node

This function should be used to get the
value of a property of a document node

=verbatim
 text = mxml:: mxml::GetProperty(<node pointer>,<string identifier>)
=noverbatim
*/
besFUNCTION(GetProperty)
mxml_node_t* node;
const char* attr;
char* pszValue;

besARGUMENTS("pz")
    &node,&attr
  besARGEND

pszValue = mxmlElementGetAttr(node, attr);

besSET_RETURN_STRING(pszValue);
besEND

/**
=section GetNode
=H Get a handle to a specified node

This function should be used to get the handle of a specific node.
It uses XPATH syntax, which resembles a UNIX path.

Ex, node = mxml::GetNode(doc, "/stufflist/stuff_test3/painting/img")

=verbatim
 node = mxml::GetNode(<node pointer>,<path-like string>)
=noverbatim
*/
besFUNCTION(GetNode)
mxml_node_t *rootNode, *node;
char *pszValue;
char *token, tmpStr[_MAX_PATH];

besARGUMENTS("pz")
    &rootNode,&pszValue
  besARGEND

node = rootNode;

memset(tmpStr,0,sizeof(tmpStr));
strncpy(tmpStr, pszValue, strlen(pszValue));


token = strtok(tmpStr, "/");
  while ( token  ) {
node = mxmlFindElement(node,node,token,NULL,NULL,MXML_DESCEND);
    token = strtok( NULL, "/" );
  }

besRETURN_POINTER(node);
besEND

/**
=section SaveDoc
=H Save to an XML file

This function should be used to save the contents of an XML tree
to a disk file

=verbatim
 mxml::SaveDoc(<DOC (root) node pointer>,<string filename>)
=noverbatim
*/
besFUNCTION(SaveDoc)
mxml_node_t* node;
const char* fileName;
FILE *fp;
int retVal;

besARGUMENTS("pz")
    &node,&fileName
  besARGEND

fp = fopen(fileName, "w");
  if(fp == NULL) {
    besRETURN_LONG(-1);
  }

retVal = mxmlSaveFile(node, fp, MXML_NO_CALLBACK);
fclose(fp);
besRETURN_LONG(retVal);
besEND

/**
=section NewDoc
=H Create a new XML document in memory

This function should be used to create a new XML document in memory.

The second parameter (xml version) is optional.  If not provided,
it defaults to version="1.0"

It would create a header that looks like:
<?xml version="1.0">

=verbatim
 doc = mxml::NewDoc(<string version>)
=noverbatim
*/
besFUNCTION(NewDoc)
mxml_node_t* node;
char* pszVersion;


besARGUMENTS("[z]")
    &pszVersion
  besARGEND

node = mxmlNewXML(pszVersion);
besRETURN_POINTER(node);

besEND

/**
=section FreeDoc
=H Releases/Destroys an XML tree in memory

This function should be used to delete an new XML document in memory.

=verbatim
 mxml::FreeDoc(<doc pointer>)
=noverbatim
*/
besFUNCTION(FreeDoc)
mxml_node_t* node;

besARGUMENTS("p")
    &node
  besARGEND

if (node) mxmlDelete(node);
besEND


/*
Exported Function List
*/
SLFST XML_SLFST[] ={

{ "versmodu" , versmodu },
{ "bootmodu" , bootmodu },
{ "finimodu" , finimodu },
{ "LoadDoc" , LoadDoc },
{ "GetNext" , GetNext },
{ "GetChild" , GetChild },
{ "GetNodeValue", GetNodeValue },
{ "GetNode" , GetNode },
{ "SaveDoc" , SaveDoc },
{ "NewDoc" , NewDoc },
{ "FreeDoc" , FreeDoc },
{ "GetProperty", GetProperty },
{ NULL , NULL }
  };

I have attached the 64 bit Linux version of the mxml extension module. (binary, source, example and readme included)

Support

  • Administrator
  • *****
  • Posts: 19
    • View Profile
Re: ScriptBasic Mini-XML Extension Module
« Reply #2 on: July 28, 2011, 11:05:13 PM »
Extension modules and their seamless integration with the language API is one of the most powerful aspects of the language. SB can morph into whatever your needs may be. The SB macro API interface makes interfacing with external libraries a breeze.


Support

  • Administrator
  • *****
  • Posts: 19
    • View Profile
Re: ScriptBasic Mini-XML Extension Module
« Reply #3 on: July 29, 2011, 01:51:50 PM »
There is a 32 bit version offered in this tread as an attachment. Did you miss it or do have other reasons for trying to use a 64 bit version on a 32 bit system? If you run make in the extension libraries directory, you could generate the extension module on your own system. The results of the compile will be in the bin directory structure and you will have to copy it to where you have defined the module directory in the basic.conf file.

Quote
also are the SB modules different for Linux then for windows, different sets of modules.

The extension modules are DLLs/Shared Objects (.so) and are generated for the platform they run under.
« Last Edit: July 29, 2011, 01:54:42 PM by support »