From 2adc7a133a25f49cb3027a100cb8933f9c6fd0ab Mon Sep 17 00:00:00 2001 From: "Zane U. Ji" Date: Tue, 20 May 2014 20:51:28 +0800 Subject: [PATCH] Feature #155 XPath - functions --- ChangeLog | 1 + src/wraplibxml.cpp | 114 ++++++++++++++++++++++++++++++++++++--------- src/wraplibxml.h | 1 + 3 files changed, 93 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9762e55..be2c8be 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,6 @@ 1.2.1.2 + Feature #69 Add "current XPath" shortcut + + Feature #155 XPath - functions + Click on the error message to jump to the error location * Bug #99 fix desktop file (Marco Rodrigues) diff --git a/src/wraplibxml.cpp b/src/wraplibxml.cpp index 8acca39..00a52e2 100644 --- a/src/wraplibxml.cpp +++ b/src/wraplibxml.cpp @@ -385,7 +385,6 @@ bool WrapLibxml::xpath ( const wxString &xpath, const std::string &utf8DocBuf, xmlXPathContextPtr context = NULL; xmlXPathObjectPtr result = NULL; - xmlNodeSetPtr nodeset = NULL; context = xmlXPathNewContext ( docPtr ); if ( !context ) @@ -406,28 +405,7 @@ bool WrapLibxml::xpath ( const wxString &xpath, const std::string &utf8DocBuf, bool xpathIsValid = ( result ) ? true : false; - while ( result != NULL ) - { - if ( xmlXPathNodeSetIsEmpty ( result->nodesetval ) ) - break; - xmlBufferPtr bufferPtr = xmlBufferCreate(); - if ( bufferPtr == NULL ) - break; - nodeset = result->nodesetval; - for ( int i = 0; i < nodeset->nodeNr; i++ ) - { - xmlNodePtr node = nodeset->nodeTab[i]; - if ( !node ) - break; - xmlNodeDump ( bufferPtr, NULL, node, 0, 1 ); - - output += ( const char * ) xmlBufferContent ( bufferPtr ); - output += '\n'; - xmlBufferEmpty ( bufferPtr ); - } - xmlBufferFree ( bufferPtr ); - break; - } + output = dumpXPathObject ( result ); xmlXPathFreeObject ( result ); xmlXPathFreeContext ( context ); @@ -437,6 +415,96 @@ bool WrapLibxml::xpath ( const wxString &xpath, const std::string &utf8DocBuf, return xpathIsValid; } +std::string WrapLibxml::dumpXPathObject ( xmlXPathObjectPtr obj ) +{ + std::stringstream sstream; + if ( !obj ) + return sstream.str(); + + switch ( obj->type ) + { + case XPATH_NODESET: + { + if ( xmlXPathNodeSetIsEmpty ( obj->nodesetval ) ) + break; + + xmlBufferPtr bufferPtr = xmlBufferCreate(); + if ( bufferPtr == NULL ) + break; + + xmlNodeSetPtr nodeset = obj->nodesetval; + for ( int i = 0; i < nodeset->nodeNr; i++ ) + { + xmlNodePtr node = nodeset->nodeTab[i]; + if ( !node ) + break; + xmlNodeDump ( bufferPtr, NULL, node, 0/*level*/, TRUE/*format*/ ); + + sstream << ( const char * ) xmlBufferContent ( bufferPtr ) + << '\n'; + xmlBufferEmpty ( bufferPtr ); + } + xmlBufferFree ( bufferPtr ); + break; + } + + case XPATH_BOOLEAN: + sstream << !!obj->boolval; + break; + + case XPATH_NUMBER: + switch ( xmlXPathIsInf ( obj->floatval ) ) + { + case 1: + sstream << wxString ( _("Infinity") ).utf8_str(); + break; + case -1: + sstream << wxString ( _("-Infinity") ).utf8_str(); + break; + default: + if ( xmlXPathIsNaN ( obj->floatval ) ) + sstream << wxString ( _("NaN") ).utf8_str(); + else + sstream << obj->floatval; + break; + } + break; + + case XPATH_STRING: + sstream << obj->stringval; + break; + + case XPATH_POINT: + xmlBufferPtr bufferPtr; + bufferPtr = xmlBufferCreate(); + if ( bufferPtr == NULL ) + break; + xmlNodeDump ( bufferPtr, NULL, ( xmlNodePtr ) obj->user, + 1/*level*/, TRUE/*format*/ ); + sstream << xmlBufferContent ( bufferPtr ); + xmlBufferFree ( bufferPtr ); + break; + + case XPATH_RANGE: + case XPATH_LOCATIONSET: + case XPATH_XSLT_TREE: + default: + FILE *fp = tmpfile(); + xmlXPathDebugDumpObject ( fp, obj, 0/*depth*/ ); + + fpos_t size = ftell ( fp ); + std::string str; + str.resize ( size ); + fseek ( fp, 0, SEEK_SET ); + fread ( ( char * ) str.c_str(), 1, str.capacity(), fp ); + fclose ( fp ); + + return str; + } + + return sstream.str(); +} + bool WrapLibxml::xslt ( const wxString &styleFileName, const std::string &utf8DocBuf, diff --git a/src/wraplibxml.h b/src/wraplibxml.h index ed9295e..c5a8997 100644 --- a/src/wraplibxml.h +++ b/src/wraplibxml.h @@ -76,6 +76,7 @@ class WrapLibxml const wxString &xpath, const std::string &utf8DocBuf, const wxString &docFileName ); + std::string dumpXPathObject ( xmlXPathObjectPtr obj ); bool xslt ( const wxString &styleFileName, const std::string &utf8DocBuf,