[GB.XML]
* NEW: Added a new Document property to XMLExplorer. * NEW: Added the Name and Value properties to XMLReader.Node.Attributes and XMLNode.Attributes, to get the name and value of the enumerated attribute. * BUG: Fixed the XMLNode.Attributes enumeration. * BUG: Fixed XMLExplorer taking the document itself as a node. * OPT: Rewrote internal exception handling. [GB.XML.XSLT] * NEW: Added a new method XSLT.TransformToString() that returns a string instead of an XML document. * BUG: Fixed internal error management. git-svn-id: svn://localhost/gambas/trunk@6416 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
parent
3dbf3ca320
commit
c41939ed3b
16 changed files with 327 additions and 248 deletions
|
@ -74,7 +74,7 @@ try
|
|||
}
|
||||
catch(XMLParseException &e)
|
||||
{
|
||||
GB.Error(e.what());
|
||||
GB.Error(e.errorWhat);
|
||||
GB.ReturnNull();
|
||||
}
|
||||
|
||||
|
@ -94,7 +94,7 @@ try
|
|||
}
|
||||
catch(XMLParseException &e)
|
||||
{
|
||||
GB.Error(e.what());
|
||||
GB.Error(e.errorWhat);
|
||||
}
|
||||
|
||||
END_METHOD
|
||||
|
@ -128,7 +128,7 @@ else
|
|||
}
|
||||
catch(XMLParseException &e)
|
||||
{
|
||||
GB.Error(e.what());
|
||||
GB.Error(e.errorWhat);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ try
|
|||
}
|
||||
catch(XMLParseException &e)
|
||||
{
|
||||
GB.Error(e.what());
|
||||
GB.Error(e.errorWhat);
|
||||
}
|
||||
|
||||
END_METHOD
|
||||
|
|
|
@ -139,7 +139,7 @@ try
|
|||
}
|
||||
catch(XMLParseException &e)
|
||||
{
|
||||
GB.Error(e.what());
|
||||
GB.Error(e.errorWhat);
|
||||
}
|
||||
END_METHOD
|
||||
|
||||
|
@ -253,7 +253,7 @@ try
|
|||
}
|
||||
catch(XMLParseException &e)
|
||||
{
|
||||
GB.Error(e.what());
|
||||
GB.Error(e.errorWhat);
|
||||
}
|
||||
GB.ReturnObject(array);
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ try
|
|||
}
|
||||
catch(XMLParseException &e)
|
||||
{
|
||||
GB.Error(e.what());
|
||||
GB.Error(e.errorWhat);
|
||||
}
|
||||
|
||||
|
||||
|
@ -105,12 +105,25 @@ GB.ReturnInteger(THIS->state);
|
|||
|
||||
END_PROPERTY
|
||||
|
||||
BEGIN_METHOD(CExplorer_document, GB_OBJECT doc)
|
||||
BEGIN_METHOD(CExplorer_load, GB_OBJECT doc)
|
||||
|
||||
THIS->Load((Document*)(VARGOBJ(CDocument, doc)->node));
|
||||
|
||||
END_METHOD
|
||||
|
||||
BEGIN_PROPERTY(CExplorer_document)
|
||||
|
||||
if(READ_PROPERTY)
|
||||
{
|
||||
XML_ReturnNode(THIS->loadedDocument);
|
||||
}
|
||||
else
|
||||
{
|
||||
THIS->Load((Document*)(VPROPOBJ(CDocument)->node));
|
||||
}
|
||||
|
||||
END_PROPERTY
|
||||
|
||||
GB_DESC CExplorerReadFlagsDesc[] =
|
||||
{
|
||||
GB_DECLARE(".XmlExplorerReadFlags", 0), GB_VIRTUAL_CLASS(),
|
||||
|
@ -127,7 +140,8 @@ GB_DESC CExplorerDesc[] =
|
|||
|
||||
GB_METHOD("_new", "", CExplorer_new, "[(Document)XmlDocument]"),
|
||||
GB_METHOD("_free", "", CExplorer_free, ""),
|
||||
GB_METHOD("Load", "", CExplorer_document, "(Document)XmlDocument"),
|
||||
GB_METHOD("Load", "", CExplorer_load, "(Document)XmlDocument"),
|
||||
GB_PROPERTY("Document", "XMLDocument", CExplorer_document),
|
||||
GB_PROPERTY_SELF("ReadFlags", ".XmlExplorerReadFlags"),
|
||||
GB_PROPERTY_READ("Node", "XmlNode", CExplorer_Node),
|
||||
GB_PROPERTY_READ("Eof", "b", CExplorer_eof),
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "serializer.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#define THISOBJ ((CNode*)_object)
|
||||
#define THIS (static_cast<CNode*>(_object)->node)
|
||||
|
||||
#define NODE_BASE 0
|
||||
|
@ -35,8 +36,10 @@
|
|||
#define NODE_COMMENT 3
|
||||
#define NODE_CDATA 4
|
||||
#define NODE_ATTRIBUTE 5
|
||||
#define NODE_DOCUMENT 6
|
||||
|
||||
BEGIN_METHOD_VOID(CNode_new)
|
||||
|
||||
if(XMLNode_NoInstanciate()) return;
|
||||
|
||||
|
||||
|
@ -253,13 +256,43 @@ else
|
|||
*reinterpret_cast<Attribute**>(GB.GetEnum()) = attr;
|
||||
}
|
||||
|
||||
THISOBJ->curAttrEnum = attr;
|
||||
|
||||
if(attr == 0) {GB.StopEnum(); return;}
|
||||
|
||||
|
||||
XML_ReturnNode(attr);
|
||||
|
||||
|
||||
END_METHOD
|
||||
|
||||
|
||||
BEGIN_PROPERTY(CElementAttributes_name)
|
||||
|
||||
if(!THISOBJ->curAttrEnum)
|
||||
{
|
||||
GB.Error("No enumerated attribute available");
|
||||
GB.ReturnNull();
|
||||
return;
|
||||
}
|
||||
|
||||
GB.ReturnNewString(THISOBJ->curAttrEnum->attrName, THISOBJ->curAttrEnum->lenAttrName);
|
||||
|
||||
END_PROPERTY
|
||||
|
||||
BEGIN_PROPERTY(CElementAttributes_value)
|
||||
|
||||
if(!THISOBJ->curAttrEnum)
|
||||
{
|
||||
GB.Error("No enumerated attribute available");
|
||||
GB.ReturnNull();
|
||||
return;
|
||||
}
|
||||
|
||||
GB.ReturnNewString(THISOBJ->curAttrEnum->attrValue, THISOBJ->curAttrEnum->lenAttrValue);
|
||||
|
||||
END_PROPERTY
|
||||
|
||||
BEGIN_PROPERTY(CNode_childNodes)
|
||||
|
||||
GB_ARRAY array;
|
||||
|
@ -341,6 +374,8 @@ GB_DESC CElementAttributesDesc[] =
|
|||
GB_METHOD("_put", "s", CElementAttributes_put, "(Value)s(Name)s"),
|
||||
GB_METHOD("_next", "XmlNode", CElementAttributes_next, ""),
|
||||
GB_PROPERTY_READ("Count", "i", CElementAttributes_count),
|
||||
GB_PROPERTY_READ("Name", "s", CElementAttributes_name),
|
||||
GB_PROPERTY_READ("Value", "s", CElementAttributes_value),
|
||||
GB_END_DECLARE
|
||||
};
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ try
|
|||
}
|
||||
catch(XMLParseException &e)
|
||||
{
|
||||
GB.Error(e.what());
|
||||
GB.Error(e.errorWhat);
|
||||
}
|
||||
|
||||
END_METHOD
|
||||
|
@ -144,18 +144,6 @@ GB.ReturnNewString(attr->attrValue, attr->lenAttrValue);
|
|||
|
||||
END_METHOD
|
||||
|
||||
/*BEGIN_METHOD(CReaderNodeAttr_put, GB_STRING value; GB_STRING name)
|
||||
|
||||
if(!THIS->foundNode)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if(!THIS->foundNode->isElement()) return;
|
||||
THIS->foundNode->toElement()->setAttribute(STRING(name), LENGTH(name),
|
||||
STRING(value), LENGTH(value));
|
||||
|
||||
END_METHOD*/
|
||||
|
||||
BEGIN_PROPERTY(CReaderNodeAttr_count)
|
||||
|
||||
if(!THIS->foundNode || THIS->state == READ_END_CUR_ELEMENT)
|
||||
|
@ -175,6 +163,32 @@ GB.ReturnInteger(0);
|
|||
|
||||
END_PROPERTY
|
||||
|
||||
BEGIN_PROPERTY(CReaderNodeAttr_name)
|
||||
|
||||
if(!THIS->curAttrEnum)
|
||||
{
|
||||
GB.Error("No enumerated attribute available");
|
||||
GB.ReturnNull();
|
||||
return;
|
||||
}
|
||||
|
||||
GB.ReturnNewString(THIS->curAttrEnum->attrName, THIS->curAttrEnum->lenAttrName);
|
||||
|
||||
END_PROPERTY
|
||||
|
||||
BEGIN_PROPERTY(CReaderNodeAttr_value)
|
||||
|
||||
if(!THIS->curAttrEnum)
|
||||
{
|
||||
GB.Error("No enumerated attribute available");
|
||||
GB.ReturnNull();
|
||||
return;
|
||||
}
|
||||
|
||||
GB.ReturnNewString(THIS->curAttrEnum->attrValue, THIS->curAttrEnum->lenAttrValue);
|
||||
|
||||
END_PROPERTY
|
||||
|
||||
BEGIN_METHOD(CReaderReadFlags_get, GB_INTEGER flag)
|
||||
|
||||
int flag = VARG(flag);
|
||||
|
@ -193,34 +207,6 @@ END_METHOD
|
|||
|
||||
BEGIN_PROPERTY(CReaderNode_type)
|
||||
|
||||
/*if(!THIS->foundNode)
|
||||
{
|
||||
GB.ReturnInteger(0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(THIS->curAttrEnum)
|
||||
{
|
||||
GB.ReturnInteger(READ_ATTRIBUTE);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(THIS->foundNode->getType())
|
||||
{
|
||||
case Node::ElementNode:
|
||||
GB.ReturnInteger(NODE_ELEMENT);break;
|
||||
case Node::Comment:
|
||||
GB.ReturnInteger(NODE_COMMENT);break;
|
||||
case Node::NodeText:
|
||||
GB.ReturnInteger(NODE_TEXT);break;
|
||||
case Node::CDATA:
|
||||
GB.ReturnInteger(NODE_CDATA);break;
|
||||
default:
|
||||
GB.ReturnInteger(0);
|
||||
}
|
||||
*/
|
||||
|
||||
GB.ReturnInteger(THIS->state);
|
||||
END_PROPERTY
|
||||
|
||||
|
@ -299,10 +285,6 @@ BEGIN_PROPERTY(CReader_storedNodes)
|
|||
|
||||
if(!READ_PROPERTY) return;
|
||||
|
||||
//GBI::ObjectArray<Node> *nodes = new GBI::ObjectArray<Node>("XmlNode", *(THIS->storedElements));
|
||||
//GB.ReturnObject(nodes->array);
|
||||
//delete nodes;
|
||||
|
||||
GB.ReturnObject(0);
|
||||
|
||||
END_PROPERTY
|
||||
|
@ -369,9 +351,10 @@ GB_DESC CReaderNodeAttributesDesc[] =
|
|||
GB_DECLARE(".XmlReader.Node.Attributes", 0), GB_VIRTUAL_CLASS(),
|
||||
|
||||
GB_METHOD("_get", "s", CReaderNodeAttr_get, "(Name)s"),
|
||||
//GB_METHOD("_put", "s", CReaderNodeAttr_put, "(Value)s(Name)s"),
|
||||
GB_METHOD("_next", "s", CReaderNodeAttr_next, ""),
|
||||
GB_PROPERTY_READ("Count", "i", CReaderNodeAttr_count),
|
||||
GB_PROPERTY_READ("Name", "i", CReaderNodeAttr_name),
|
||||
GB_PROPERTY_READ("Value", "i", CReaderNodeAttr_value),
|
||||
|
||||
GB_END_DECLARE
|
||||
};
|
||||
|
|
|
@ -166,7 +166,7 @@ void XMLDocument_SetContent(Document *doc, const char *content, size_t len) thro
|
|||
{
|
||||
if(doc->docType == XMLDocumentType)//Strict document
|
||||
{
|
||||
throw XMLParseException("Extra root element", 0, 0, 0);
|
||||
throw XMLParseException_New("Extra root element", 0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -178,50 +178,9 @@ void XMLDocument_SetContent(Document *doc, const char *content, size_t len) thro
|
|||
|
||||
free(elements);
|
||||
if(newRoot) doc->root = (Element*)newRoot;
|
||||
|
||||
|
||||
/*if(!newRoot)
|
||||
{
|
||||
throw XMLParseException("No valid element root found", 0, 0, 0);
|
||||
}*/
|
||||
|
||||
//this->setRoot(newRoot);
|
||||
|
||||
//if(!root) throw HTMLParseException(0, 0, "somewhere", "No valid root element found.");
|
||||
}
|
||||
|
||||
/*
|
||||
void Document::toString(char **output, size_t *len, int indent)
|
||||
{
|
||||
//<?xml version="1.0" encoding="UTF-8"?> //Len = 38
|
||||
*len = 38 + (indent >= 0 ? 1 : 0); root->addStringLen(len, indent);
|
||||
*output = (char*)malloc(*len);
|
||||
memcpy(*output, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>", 38);
|
||||
*output += 38;
|
||||
if(indent >= 0)
|
||||
{
|
||||
**output = SCHAR_N;
|
||||
++(*output);
|
||||
}
|
||||
root->addString(output, indent);
|
||||
(*output) -= (*len);
|
||||
}
|
||||
|
||||
void Document::toGBString(char **output, size_t *len, int indent)
|
||||
{
|
||||
//<?xml version="1.0" encoding="UTF-8"?> //Len = 38
|
||||
*len = 38 + (indent >= 0 ? 1 : 0); root->addStringLen(len, indent);
|
||||
*output = GB.TempString(0, *len);
|
||||
memcpy(*output, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>", 38);
|
||||
*output += 38;
|
||||
if(indent >= 0)
|
||||
{
|
||||
**output = SCHAR_N;
|
||||
++(*output);
|
||||
}
|
||||
root->addString(output, indent);
|
||||
(*output) -= (*len);
|
||||
}*/
|
||||
|
||||
void XMLDocument_Save(Document *doc, const char *fileName, bool indent)
|
||||
{
|
||||
|
|
|
@ -55,9 +55,10 @@ void Explorer::Init()
|
|||
|
||||
void Explorer::Load(Document *doc)
|
||||
{
|
||||
//UNREF(loadedDocument);
|
||||
Clear();
|
||||
loadedDocument = doc;
|
||||
CNode *obj = XMLNode_GetGBObject(loadedDocument);
|
||||
GB.Ref(obj);
|
||||
//GB.Ref(doc);
|
||||
|
||||
Read();
|
||||
|
@ -66,7 +67,11 @@ void Explorer::Load(Document *doc)
|
|||
|
||||
void Explorer::Clear()
|
||||
{
|
||||
if(loadedDocument) XMLNode_DestroyParent((Node*)loadedDocument);
|
||||
if(loadedDocument)
|
||||
{
|
||||
CNode *obj = XMLNode_GetGBObject(loadedDocument);
|
||||
GB.Unref(POINTER(&obj));
|
||||
}
|
||||
loadedDocument = 0;
|
||||
curNode = 0;
|
||||
this->eof = false;
|
||||
|
@ -104,7 +109,7 @@ int Explorer::MoveNext()
|
|||
return nextNode->type;
|
||||
}
|
||||
//si plus d'enfants ni de frère, on remonte
|
||||
else if(curNode->parent && curNode != loadedDocument->root)
|
||||
else if(curNode->parent && curNode != loadedDocument->root && curNode->parent != loadedDocument)
|
||||
{
|
||||
curNode = curNode->parent;
|
||||
endElement = true;
|
||||
|
|
|
@ -21,6 +21,7 @@ using namespace std;
|
|||
|
||||
#define DEBUG std::cerr << "XMLDBG (" << __FILE__ << ":" <<__LINE__ << ") :"
|
||||
#define DEBUGH DEBUG << endl
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct Node
|
||||
|
@ -98,6 +99,17 @@ typedef TextNode CommentNode;
|
|||
|
||||
typedef TextNode CDATANode;
|
||||
|
||||
typedef struct XMLParseException
|
||||
{
|
||||
char *near;
|
||||
size_t lenNear;
|
||||
|
||||
size_t line;
|
||||
size_t column;
|
||||
|
||||
char *errorWhat;
|
||||
}XMLParseException;
|
||||
|
||||
//Gambas XML component interface
|
||||
|
||||
#define XML_INTERFACE_VERSION 1
|
||||
|
|
|
@ -13,11 +13,13 @@ extern "C" GB_INTERFACE GB;
|
|||
|
||||
|
||||
struct Node;
|
||||
struct Attribute;
|
||||
|
||||
typedef struct CNode
|
||||
{
|
||||
GB_BASE ob;
|
||||
Node *node;
|
||||
Attribute *curAttrEnum;
|
||||
}CNode;
|
||||
|
||||
typedef CNode CDocument;
|
||||
|
|
|
@ -95,6 +95,9 @@ void XMLNode_NewGBObject(Node *node)
|
|||
case Node::DocumentNode:
|
||||
node->GBObject = (CNode*)GB.New(GB.FindClass("XmlDocument"), 0, 0);
|
||||
break;
|
||||
case Node::AttributeNode:
|
||||
node->GBObject = (CNode*)GB.New(GB.FindClass("XmlNode"), 0, 0);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "FATAL : tried to create a Gambas object with invalid type.");
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
|
@ -129,21 +129,21 @@ Node** parseXML(char const *data, const size_t lendata, size_t *nodeCount) throw
|
|||
if(!curElement)//Pas d'élément courant
|
||||
{
|
||||
//ERREUR : CLOSING TAG WHEREAS NONE IS OPEN
|
||||
throw(XMLParseException("Closing tag whereas none is open",
|
||||
throw(XMLParseException_New("Closing tag whereas none is open",
|
||||
data, lendata, pos - 1));
|
||||
|
||||
}
|
||||
if((endData) < pos + curElement->lenTagName)//Impossible que les tags correspondent
|
||||
{
|
||||
//ERREUR : TAG MISMATCH
|
||||
throw(XMLParseException("Tag mismatch",
|
||||
throw(XMLParseException_New("Tag mismatch",
|
||||
data, lendata, pos - 1));
|
||||
}
|
||||
//Les tags ne correspondent pas
|
||||
else if(memcmp(pos, curElement->tagName, curElement->lenTagName) != 0)
|
||||
{
|
||||
//ERREUR : TAG MISMATCH
|
||||
throw(XMLParseException("Tag mismatch",
|
||||
throw(XMLParseException_New("Tag mismatch",
|
||||
data, lendata, pos - 1));
|
||||
}
|
||||
else//Les tags correspondent, on remonte
|
||||
|
@ -165,7 +165,7 @@ Node** parseXML(char const *data, const size_t lendata, size_t *nodeCount) throw
|
|||
if(!tag)//Commentaire sans fin
|
||||
{
|
||||
//ERREUR : NEVER-ENDING COMMENT
|
||||
throw(XMLParseException("Never-ending comment",
|
||||
throw(XMLParseException_New("Never-ending comment",
|
||||
data, lendata, pos - 1));
|
||||
}
|
||||
|
||||
|
@ -182,7 +182,7 @@ Node** parseXML(char const *data, const size_t lendata, size_t *nodeCount) throw
|
|||
if(!tag)//Cdata sans fin
|
||||
{
|
||||
//ERREUR : UNENDED CDATA
|
||||
throw(XMLParseException("Never-ending CDATA",
|
||||
throw(XMLParseException_New("Never-ending CDATA",
|
||||
data, lendata, pos - 1));
|
||||
}
|
||||
|
||||
|
@ -198,7 +198,7 @@ Node** parseXML(char const *data, const size_t lendata, size_t *nodeCount) throw
|
|||
tag = (char*)memchr(pos, '>', endData - pos);
|
||||
if(!tag)//Doctype sans fin
|
||||
{
|
||||
throw(XMLParseException("Never-ending DOCTYPE",
|
||||
throw(XMLParseException_New("Never-ending DOCTYPE",
|
||||
data, lendata, pos - 1));
|
||||
}
|
||||
|
||||
|
@ -208,7 +208,7 @@ Node** parseXML(char const *data, const size_t lendata, size_t *nodeCount) throw
|
|||
else// ... ?
|
||||
{
|
||||
//ERREUR : INVALID TAG
|
||||
throw(XMLParseException("Invalid Tag",
|
||||
throw(XMLParseException_New("Invalid Tag",
|
||||
data, lendata, pos - 1));
|
||||
}
|
||||
}
|
||||
|
@ -217,7 +217,7 @@ Node** parseXML(char const *data, const size_t lendata, size_t *nodeCount) throw
|
|||
tag = (char*)memchrs(pos, endData - pos, "?>", 2);//Looking for the end of the PI
|
||||
if(!tag)//Endless PI
|
||||
{
|
||||
throw(XMLParseException("Never-ending Processing instruction",
|
||||
throw(XMLParseException_New("Never-ending Processing instruction",
|
||||
data, lendata, pos - 1));
|
||||
}
|
||||
|
||||
|
@ -228,7 +228,7 @@ Node** parseXML(char const *data, const size_t lendata, size_t *nodeCount) throw
|
|||
else// ... ?
|
||||
{
|
||||
//ERREUR : INVALID TAG
|
||||
throw(XMLParseException("Invalid Tag",
|
||||
throw(XMLParseException_New("Invalid Tag",
|
||||
data, lendata, pos - 1));
|
||||
}
|
||||
}//Si tout va bien, on a un nouvel élément
|
||||
|
@ -239,7 +239,7 @@ Node** parseXML(char const *data, const size_t lendata, size_t *nodeCount) throw
|
|||
if(pos > endData)
|
||||
{
|
||||
//ERREUR : NEVER-ENDING TAG
|
||||
throw(XMLParseException("Never-ending tag",
|
||||
throw(XMLParseException_New("Never-ending tag",
|
||||
data, lendata, pos - 1));
|
||||
}
|
||||
}
|
||||
|
@ -282,7 +282,7 @@ Node** parseXML(char const *data, const size_t lendata, size_t *nodeCount) throw
|
|||
else
|
||||
{
|
||||
//ERREUR : INVALID TAG
|
||||
throw(XMLParseException("Invalid tag",
|
||||
throw(XMLParseException_New("Invalid tag",
|
||||
data, lendata, pos - 1));
|
||||
}
|
||||
}
|
||||
|
@ -295,7 +295,7 @@ Node** parseXML(char const *data, const size_t lendata, size_t *nodeCount) throw
|
|||
if(delimiter != '"' && delimiter != '\'')
|
||||
{
|
||||
//ERREUR : EXPECTED ATTRIBUTE DELIMITER
|
||||
throw(XMLParseException("Expected attribute delimiter",
|
||||
throw(XMLParseException_New("Expected attribute delimiter",
|
||||
data, lendata, pos - 1));
|
||||
}
|
||||
pos++;
|
||||
|
|
|
@ -142,7 +142,7 @@ int Reader::ReadChar(char car)
|
|||
{
|
||||
if(inTag)//Si on est déjà dans un tag
|
||||
{
|
||||
throw XMLParseException("Invalid tag Name", pos);
|
||||
throw XMLParseException_New("Invalid tag Name", pos);
|
||||
}
|
||||
inNewTag = true;
|
||||
inTagName = true;
|
||||
|
|
|
@ -280,14 +280,47 @@ void XML_Format(GB_VALUE *value, char* &dst, size_t &lenDst)
|
|||
|
||||
/************************************ Error Management ************************************/
|
||||
|
||||
void XMLParseException_AnalyzeText(XMLParseException *ex, const char *text, const size_t lenText, const char *posFailed) throw();
|
||||
|
||||
void ThrowXMLParseException(const char* nerror, const char *text, const size_t lenText, const char *posFailed)
|
||||
{
|
||||
throw XMLParseException(nerror, text, lenText, posFailed);
|
||||
throw XMLParseException_New(nerror, text, lenText, posFailed);
|
||||
}
|
||||
|
||||
XMLParseException::XMLParseException(const char *nerror, const char *data, const size_t lenData, const char *posFailed) throw()
|
||||
: near(0), error(0), lenError(0), lenNear(0), line(1), column(1)
|
||||
XMLParseException* XMLParseException_New()//Void initializer
|
||||
{
|
||||
XMLParseException *exception = new XMLParseException;
|
||||
memset(exception, 0, sizeof(XMLParseException));
|
||||
exception->line = 1;
|
||||
exception->column = 1;
|
||||
return exception;
|
||||
}
|
||||
|
||||
XMLParseException* XMLParseException_New(const char *nerror, size_t posFailed)
|
||||
{
|
||||
XMLParseException *exception = XMLParseException_New();
|
||||
size_t lenError;
|
||||
char *error;
|
||||
|
||||
lenError = strlen(nerror) + 1;
|
||||
error = (char*) malloc(lenError);
|
||||
memcpy(error, nerror, lenError);
|
||||
|
||||
exception->errorWhat = (char*)malloc(37 + lenError);
|
||||
sprintf(exception->errorWhat, "Parse error : %s !\n Position %zu", error, (size_t)posFailed);
|
||||
exception->errorWhat[36 + lenError] = 0;
|
||||
|
||||
free(error);
|
||||
|
||||
return exception;
|
||||
}
|
||||
|
||||
XMLParseException* XMLParseException_New(const char *nerror, const char *data, const size_t lenData, const char *posFailed) throw()
|
||||
{
|
||||
XMLParseException *exception = XMLParseException_New();
|
||||
size_t lenError;
|
||||
char *error;
|
||||
|
||||
lenError = strlen(nerror) + 1;
|
||||
error = (char*) malloc(lenError);
|
||||
memcpy(error, nerror, lenError);
|
||||
|
@ -296,76 +329,63 @@ XMLParseException::XMLParseException(const char *nerror, const char *data, const
|
|||
|
||||
if(posFailed == 0)
|
||||
{
|
||||
errorWhat = (char*)malloc(17 + lenError);
|
||||
sprintf(errorWhat, "Parse error : %s !", error);
|
||||
errorWhat[16 + lenError] = 0;
|
||||
return;
|
||||
exception->errorWhat = (char*)malloc(17 + lenError);
|
||||
sprintf(exception->errorWhat, "Parse error : %s !", error);
|
||||
exception->errorWhat[16 + lenError] = 0;
|
||||
return exception;
|
||||
}
|
||||
else if(!data || !lenData)
|
||||
{
|
||||
errorWhat = (char*)malloc(37 + lenError);
|
||||
sprintf(errorWhat, "Parse error : %s !\n Position %zu", error, (size_t)posFailed);
|
||||
errorWhat[36 + lenError] = 0;
|
||||
return;
|
||||
exception->errorWhat = (char*)malloc(37 + lenError);
|
||||
sprintf(exception->errorWhat, "Parse error : %s !\n Position %zu", error, (size_t)posFailed);
|
||||
exception->errorWhat[36 + lenError] = 0;
|
||||
return exception;
|
||||
}
|
||||
if(posFailed > data + lenData || posFailed < data) return;
|
||||
AnalyzeText(data, lenData, posFailed);
|
||||
|
||||
if(posFailed > data + lenData || posFailed < data) return exception;
|
||||
XMLParseException_AnalyzeText(exception, data, lenData, posFailed);
|
||||
|
||||
|
||||
errorWhat = (char*)malloc(61 + lenError + lenNear);
|
||||
memset(errorWhat, 0, 61 + lenError + lenNear);
|
||||
sprintf(errorWhat, "Parse error : %s !\n Line %zu , Column %zu : \n %s", error, line, column, near);
|
||||
errorWhat[60 + lenError + lenNear] = 0;
|
||||
exception->errorWhat = (char*)malloc(61 + lenError + exception->lenNear);
|
||||
memset(exception->errorWhat, 0, 61 + lenError + exception->lenNear);
|
||||
sprintf(exception->errorWhat, "Parse error : %s !\n Line %zu , Column %zu : \n %s", error, exception->line, exception->column, exception->near);
|
||||
exception->errorWhat[60 + lenError + exception->lenNear] = 0;
|
||||
|
||||
return exception;
|
||||
}
|
||||
|
||||
XMLParseException::XMLParseException(const char *nerror, size_t posFailed) throw()
|
||||
: near(0), error(0), lenError(0), lenNear(0), line(1), column(1)
|
||||
|
||||
void XMLParseException_Free(XMLParseException* &ex) throw()
|
||||
{
|
||||
lenError = strlen(nerror) + 1;
|
||||
error = (char*) malloc(lenError);
|
||||
memcpy(error, nerror, lenError);
|
||||
|
||||
//Parse error : (errorText) !\n Line 123456789 , Column 123456789 : \n (near)
|
||||
|
||||
errorWhat = (char*)malloc(37 + lenError);
|
||||
sprintf(errorWhat, "Parse error : %s !\n Position %zu", error, posFailed);
|
||||
errorWhat[36 + lenError] = 0;
|
||||
if(ex->near) free(ex->near);
|
||||
free(ex);
|
||||
ex = 0;
|
||||
}
|
||||
|
||||
XMLParseException::~XMLParseException() throw()
|
||||
{
|
||||
if(near) free(near);
|
||||
if(error) free(error);
|
||||
}
|
||||
|
||||
void XMLParseException::AnalyzeText(const char *text, const size_t lenText, const char *posFailed) throw()
|
||||
void XMLParseException_AnalyzeText(XMLParseException *ex, const char *text, const size_t lenText, const char *posFailed) throw()
|
||||
{
|
||||
for(const char *pos = text; pos < posFailed; ++pos)
|
||||
{
|
||||
++column;
|
||||
++ex->column;
|
||||
if(*pos == '\n')
|
||||
{
|
||||
column = 1;
|
||||
++line;
|
||||
ex->column = 1;
|
||||
++ex->line;
|
||||
}
|
||||
else if(*pos == '\r')
|
||||
{
|
||||
if(*(pos + 1) == '\n') ++pos;
|
||||
column = 1;
|
||||
++line;
|
||||
ex->column = 1;
|
||||
++ex->line;
|
||||
}
|
||||
}
|
||||
|
||||
lenNear = text + lenText <= posFailed + 20 ? text + lenText - posFailed : 20;
|
||||
if(lenNear == 0) return;
|
||||
near = (char*)malloc(lenNear + 1);
|
||||
memcpy(near, posFailed, lenNear);
|
||||
near[lenNear] = 0;
|
||||
}
|
||||
|
||||
const char* XMLParseException::what() const throw()
|
||||
{
|
||||
return errorWhat;
|
||||
ex->lenNear = text + lenText <= posFailed + 20 ? text + lenText - posFailed : 20;
|
||||
if(ex->lenNear == 0) return;
|
||||
ex->near = (char*)malloc(ex->lenNear + 1);
|
||||
memcpy(ex->near, posFailed, ex->lenNear);
|
||||
ex->near[ex->lenNear] = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -46,30 +46,10 @@ void insertString(char *&src, size_t &lenSrc, const char *insert, size_t lenInse
|
|||
|
||||
bool GB_MatchString(const char *str, size_t lenStr, const char *pattern, size_t lenPattern, int mode = GB_STRCOMP_BINARY);
|
||||
|
||||
XMLParseException* XMLParseException_New(const char *nerror, size_t posFailed);
|
||||
XMLParseException* XMLParseException_New(const char *nerror, const char *data, const size_t lenData, const char *posFailed) throw();
|
||||
void ThrowXMLParseException(const char* nerror, const char *text, const size_t lenText, const char *posFailed);
|
||||
|
||||
class XMLParseException
|
||||
{
|
||||
public:
|
||||
XMLParseException(const char* nerror, const char *text, const size_t lenText, const char *posFailed) throw();
|
||||
XMLParseException(const char* nerror, size_t posFailed) throw();
|
||||
virtual ~XMLParseException() throw();
|
||||
|
||||
virtual const char* what() const throw();
|
||||
|
||||
private:
|
||||
void AnalyzeText(const char *text, const size_t lenText, const char *posFailed) throw();
|
||||
|
||||
char *near;
|
||||
char *error;
|
||||
size_t lenError;
|
||||
size_t lenNear;
|
||||
size_t line;
|
||||
size_t column;
|
||||
|
||||
char *errorWhat;
|
||||
};
|
||||
|
||||
|
||||
#endif // UTILS_H
|
||||
|
||||
|
|
|
@ -21,18 +21,73 @@
|
|||
MA 02110-1301, USA.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#define __CXSLT_C
|
||||
#include "../gb.xml.h"
|
||||
#include "../gbinterface.h"
|
||||
#include "CXSLT.h"
|
||||
|
||||
extern GB_INTERFACE GB;
|
||||
extern XML_INTERFACE XML;
|
||||
|
||||
#include <iostream>
|
||||
#include <memory.h>
|
||||
#include <libxml2/libxml/xinclude.h>
|
||||
#include <libxslt/xslt.h>
|
||||
#include <libxslt/xsltInternals.h>
|
||||
#include <libxslt/transform.h>
|
||||
#include <libxslt/xsltutils.h>
|
||||
|
||||
void XSLT_Transform(Document* doc, Document* stylesheet,char* &outDocument, size_t &outDocumentLen) throw(XSLTException)
|
||||
{
|
||||
if(!doc->childCount) throw XSLTException("Void document");
|
||||
if(!stylesheet->childCount) throw XSLTException("Void style sheet");
|
||||
|
||||
xsltStylesheetPtr sheet = 0;
|
||||
|
||||
char *StyleSheetOutput = NULL;
|
||||
size_t StyleSheetLen = 0;
|
||||
|
||||
XML.SerializeXMLNode((Node*)stylesheet, StyleSheetOutput, StyleSheetLen, -1);
|
||||
|
||||
StyleSheetOutput =(char*)realloc(StyleSheetOutput, StyleSheetLen + 1);
|
||||
StyleSheetOutput[StyleSheetLen] = 0;
|
||||
|
||||
|
||||
xmlDoc *xmlStyleSheet = xmlParseDoc((xmlChar*)(StyleSheetOutput));
|
||||
|
||||
free(StyleSheetOutput);
|
||||
|
||||
if(!(sheet=xsltParseStylesheetDoc(xmlStyleSheet))) throw XSLTException("Invalid style sheet");
|
||||
|
||||
char *DocumentOutput;
|
||||
size_t DocumentLen;
|
||||
|
||||
|
||||
XML.SerializeXMLNode((Node*)doc, DocumentOutput, DocumentLen, -1);
|
||||
|
||||
DocumentOutput =(char*)realloc(DocumentOutput, DocumentLen + 1);
|
||||
DocumentOutput[DocumentLen] = 0;
|
||||
|
||||
|
||||
xmlDoc *xmlInputDoc = xmlParseDoc((xmlChar*)(DocumentOutput));
|
||||
if(!xmlInputDoc) throw XSLTException("Unable to parse input document");
|
||||
|
||||
free(DocumentOutput);
|
||||
|
||||
xmlDoc *xmlOutDoc;
|
||||
|
||||
xmlOutDoc = xsltApplyStylesheet(sheet, xmlInputDoc, NULL);
|
||||
if (!xmlOutDoc) throw XSLTException("Unable to apply style sheet");
|
||||
|
||||
int size;
|
||||
xmlDocDumpFormatMemoryEnc(xmlOutDoc ,(xmlChar**)&outDocument, &size, "UTF-8", 1);
|
||||
outDocumentLen = size;
|
||||
|
||||
xsltFreeStylesheet(sheet);
|
||||
xmlFreeDoc(xmlOutDoc);
|
||||
|
||||
xmlFreeDoc(xmlInputDoc);
|
||||
}
|
||||
|
||||
BEGIN_METHOD(CXSLT_Transform,GB_OBJECT inputDoc;GB_OBJECT inputStyleSheet)
|
||||
|
||||
if (GB.CheckObject(VARGOBJ(CDocument,inputDoc))) return;
|
||||
|
@ -41,78 +96,67 @@ if (GB.CheckObject(VARGOBJ(CDocument,inputStyleSheet))) return;
|
|||
Document *doc = (Document*)(VARGOBJ(CDocument,inputDoc)->node),
|
||||
*stylesheet = (Document*)(VARGOBJ(CDocument,inputStyleSheet)->node);
|
||||
|
||||
if (!doc->childCount)
|
||||
{
|
||||
GB.Error("Void document");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!stylesheet->childCount)
|
||||
{
|
||||
GB.Error("Void Style Sheet");
|
||||
return;
|
||||
}
|
||||
char *buffer = 0;
|
||||
size_t size;
|
||||
|
||||
xsltStylesheetPtr sheet = 0;
|
||||
|
||||
char *StyleSheetOutput = NULL;
|
||||
size_t StyleSheetLen = 0;
|
||||
|
||||
XML.SerializeXMLNode((Node*)stylesheet, StyleSheetOutput, StyleSheetLen, -1);
|
||||
|
||||
StyleSheetOutput =(char*)realloc(StyleSheetOutput, StyleSheetLen + 1);
|
||||
StyleSheetOutput[StyleSheetLen] = 0;
|
||||
|
||||
|
||||
xmlDoc *xmlStyleSheet = xmlParseDoc((xmlChar*)(StyleSheetOutput));
|
||||
|
||||
|
||||
if(!(sheet=xsltParseStylesheetDoc(xmlStyleSheet)))
|
||||
{
|
||||
GB.Error("Invalid style sheet");
|
||||
return;
|
||||
}
|
||||
|
||||
char *DocumentOutput;
|
||||
size_t DocumentLen;
|
||||
|
||||
|
||||
XML.SerializeXMLNode((Node*)doc, DocumentOutput, DocumentLen, -1);
|
||||
|
||||
DocumentOutput =(char*)realloc(DocumentOutput, DocumentLen + 1);
|
||||
DocumentOutput[DocumentLen] = 0;
|
||||
|
||||
xmlDoc *xmlInputDoc = xmlParseDoc((xmlChar*)(DocumentOutput));
|
||||
|
||||
|
||||
xmlDoc *xmlOutDoc;
|
||||
xmlChar *buffer = 0;
|
||||
int size;
|
||||
|
||||
xmlOutDoc = xsltApplyStylesheet(sheet, xmlInputDoc, NULL);
|
||||
if (!xmlOutDoc)
|
||||
try
|
||||
{
|
||||
GB.Error("Unable to apply style sheet");
|
||||
XSLT_Transform(doc, stylesheet, buffer, size);
|
||||
}
|
||||
catch(XSLTException &ex)
|
||||
{
|
||||
GB.Error(ex.what());
|
||||
GB.ReturnNull();
|
||||
return;
|
||||
}
|
||||
|
||||
xmlDocDumpFormatMemoryEnc(xmlOutDoc ,&buffer, &size, "UTF-8", 1);
|
||||
|
||||
Document *outDoc = XML.XMLDocument_New();
|
||||
|
||||
/*try
|
||||
{*/
|
||||
XML.XMLDocument_SetContent(outDoc, (char*)(buffer),size);
|
||||
//}
|
||||
/*catch(XMLParseException &e)
|
||||
try
|
||||
{
|
||||
XML.XMLDocument_SetContent(outDoc, "<?xml version=\"1.0\"?><xml></xml>", 32);
|
||||
std::cerr << "XSLT Warning : error when parsing output document : " << std::endl << e.what() << std::endl;
|
||||
}*/
|
||||
|
||||
XML.XMLDocument_SetContent(outDoc, (char*)(buffer),size);
|
||||
}
|
||||
catch(XMLParseException e)
|
||||
{
|
||||
std::cerr << "XSLT Warning : error when parsing output document : " << e.errorWhat << std::endl;
|
||||
}
|
||||
|
||||
|
||||
free(buffer);
|
||||
XML.ReturnNode(outDoc);
|
||||
|
||||
|
||||
END_METHOD
|
||||
|
||||
BEGIN_METHOD(CXSLT_TransformToString,GB_OBJECT inputDoc;GB_OBJECT inputStyleSheet)
|
||||
|
||||
if (GB.CheckObject(VARGOBJ(CDocument,inputDoc))) return;
|
||||
if (GB.CheckObject(VARGOBJ(CDocument,inputStyleSheet))) return;
|
||||
|
||||
Document *doc = (Document*)(VARGOBJ(CDocument,inputDoc)->node),
|
||||
*stylesheet = (Document*)(VARGOBJ(CDocument,inputStyleSheet)->node);
|
||||
|
||||
char *buffer = 0;
|
||||
size_t size;
|
||||
|
||||
try
|
||||
{
|
||||
XSLT_Transform(doc, stylesheet, buffer, size);
|
||||
}
|
||||
catch(XSLTException &ex)
|
||||
{
|
||||
GB.Error(ex.what());
|
||||
GB.ReturnNull();
|
||||
return;
|
||||
}
|
||||
|
||||
GB.ReturnNewString(buffer, size);
|
||||
|
||||
free(buffer);
|
||||
|
||||
END_METHOD
|
||||
|
||||
|
||||
|
||||
|
||||
GB_DESC CXsltDesc[] =
|
||||
|
@ -120,6 +164,18 @@ GB_DESC CXsltDesc[] =
|
|||
GB_DECLARE("Xslt", 0), GB_NOT_CREATABLE(),
|
||||
|
||||
GB_STATIC_METHOD ("Transform","XmlDocument",CXSLT_Transform,"(Document)XmlDocument;(StyleSheet)XmlDocument;"),
|
||||
GB_STATIC_METHOD ("TransformToString","s",CXSLT_TransformToString,"(Document)XmlDocument;(StyleSheet)XmlDocument;"),
|
||||
|
||||
GB_END_DECLARE
|
||||
};
|
||||
|
||||
|
||||
XSLTException::XSLTException(const char *error) throw()
|
||||
{
|
||||
this->error = error;
|
||||
}
|
||||
|
||||
const char *XSLTException::what()
|
||||
{
|
||||
return this->error;
|
||||
}
|
||||
|
|
|
@ -31,4 +31,14 @@
|
|||
extern GB_DESC CXsltDesc[];
|
||||
#endif
|
||||
|
||||
class XSLTException
|
||||
{
|
||||
public:
|
||||
XSLTException(const char *error) throw();
|
||||
const char* what();
|
||||
private:
|
||||
const char *error;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue