summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Mohrhard <markus.mohrhard@googlemail.com>2013-06-16 01:19:22 +0200
committerMarkus Mohrhard <markus.mohrhard@googlemail.com>2013-06-16 15:59:06 +0200
commit3b9620e18bdcb91a229e9aefef5192f346030b52 (patch)
tree521daa0fd89815baad948d26ea7d383dd910d51e
parentde8a82d9ac6ce02416aa820f82b5a3ea2598ec1c (diff)
inital work on FILTERXML function
Change-Id: Ifb884a52b275df818812f8be6cd7650dcb97849d
-rw-r--r--formula/source/core/resource/core_resource.src6
-rw-r--r--include/formula/compiler.hrc5
-rw-r--r--include/formula/opcode.hxx1
-rw-r--r--sc/CppunitTest_sc_ucalc.mk7
-rw-r--r--sc/Library_sc.mk3
-rw-r--r--sc/qa/unit/ucalc.cxx1
-rw-r--r--sc/source/core/inc/interpre.hxx2
-rw-r--r--sc/source/core/tool/interpr4.cxx1
-rw-r--r--sc/source/core/tool/interpr7.cxx93
-rw-r--r--sc/source/ui/src/scfuncs.src30
10 files changed, 143 insertions, 6 deletions
diff --git a/formula/source/core/resource/core_resource.src b/formula/source/core/resource/core_resource.src
index f4c5f9654e87..e0123f5cf92c 100644
--- a/formula/source/core/resource/core_resource.src
+++ b/formula/source/core/resource/core_resource.src
@@ -362,6 +362,7 @@ Resource RID_STRLIST_FUNCTION_NAMES_ENGLISH_ODFF
String SC_OPCODE_ERROR_NAME { Text = "#NAME?" ; };
String SC_OPCODE_ERROR_NUM { Text = "#NUM!" ; };
String SC_OPCODE_ERROR_NA { Text = "#N/A" ; };
+ String SC_OPCODE_FILTERXML { Text = "COM.MICROSOFT.FILTERXML";};
/* END defined ERROR.TYPE() values. */
};
// DO NOT CHANGE!
@@ -1995,6 +1996,11 @@ Resource RID_STRLIST_FUNCTION_NAMES
Text [ en-US ] = "#N/A" ;
};
/* END defined ERROR.TYPE() values. */
+
+ String SC_OPCODE_FILTERXML
+ {
+ Text [ en-US ] = "FILTERXML";
+ };
};
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/formula/compiler.hrc b/include/formula/compiler.hrc
index e6c6ef3d0df3..fd7453d74995 100644
--- a/include/formula/compiler.hrc
+++ b/include/formula/compiler.hrc
@@ -407,9 +407,10 @@
#define SC_OPCODE_RIGHTB 409
#define SC_OPCODE_LEFTB 410
#define SC_OPCODE_MIDB 412
-#define SC_OPCODE_LAST_OPCODE_ID 413 /* last OpCode */
+#define SC_OPCODE_FILTERXML 413
+#define SC_OPCODE_LAST_OPCODE_ID 414 /* last OpCode */
-#define SC_OPCODE_STOP_FUNCTION 412
+#define SC_OPCODE_STOP_FUNCTION 415
/*** Internal ***/
#define SC_OPCODE_INTERNAL_BEGIN 9999
diff --git a/include/formula/opcode.hxx b/include/formula/opcode.hxx
index 47e2cdc2dff4..5ebaa6bf7818 100644
--- a/include/formula/opcode.hxx
+++ b/include/formula/opcode.hxx
@@ -401,6 +401,7 @@ enum OpCodeEnum
ocHyperLink = SC_OPCODE_HYPERLINK,
ocGetPivotData = SC_OPCODE_GET_PIVOT_DATA,
ocEuroConvert = SC_OPCODE_EUROCONVERT,
+ ocFilterXML = SC_OPCODE_FILTERXML,
// internal stuff
ocInternalBegin = SC_OPCODE_INTERNAL_BEGIN,
ocTTT = SC_OPCODE_TTT,
diff --git a/sc/CppunitTest_sc_ucalc.mk b/sc/CppunitTest_sc_ucalc.mk
index dd1e64de4591..0933cb58cd1e 100644
--- a/sc/CppunitTest_sc_ucalc.mk
+++ b/sc/CppunitTest_sc_ucalc.mk
@@ -23,13 +23,14 @@ endif
$(eval $(call gb_CppunitTest_use_externals,sc_ucalc,\
boost_headers \
- mdds_headers \
- orcus \
- orcus-parser \
icu_headers \
icudata \
icui18n \
icuuc \
+ libxml2 \
+ mdds_headers \
+ orcus \
+ orcus-parser \
))
$(eval $(call gb_CppunitTest_use_libraries,sc_ucalc, \
diff --git a/sc/Library_sc.mk b/sc/Library_sc.mk
index 189d7e2bab5c..dba982bc9d34 100644
--- a/sc/Library_sc.mk
+++ b/sc/Library_sc.mk
@@ -37,11 +37,12 @@ $(eval $(call gb_Library_use_sdk_api,sc))
$(eval $(call gb_Library_use_externals,sc,\
boost_headers \
- mdds_headers \
icu_headers \
icudata \
icui18n \
icuuc \
+ libxml2 \
+ mdds_headers \
))
ifeq ($(ENABLE_TELEPATHY),TRUE)
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index 686521d3e245..734b1729d92d 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -5365,6 +5365,7 @@ void Test::testFunctionLists()
"DECIMAL",
"DOLLAR",
"EXACT",
+ "FILTERXML",
"FIND",
"FIXED",
"JIS",
diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 102b9b017b3b..36109eeac68d 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -793,6 +793,8 @@ void ScRightB();
void ScLeftB();
void ScMidB();
+void ScFilterXML();
+
static const double fMaxGammaArgument;
double GetGammaContFraction(double fA,double fX);
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 60383f0fa5e2..016345a0db49 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -4029,6 +4029,7 @@ StackVar ScInterpreter::Interpret()
case ocZW : ScZW(); break;
case ocZZR : ScZZR(); break;
case ocZins : ScZins(); break;
+ case ocFilterXML : ScFilterXML(); break;
case ocZinsZ : ScZinsZ(); break;
case ocKapz : ScKapz(); break;
case ocKumZinsZ : ScKumZinsZ(); break;
diff --git a/sc/source/core/tool/interpr7.cxx b/sc/source/core/tool/interpr7.cxx
index 1ea0f3bf0759..52b362063237 100644
--- a/sc/source/core/tool/interpr7.cxx
+++ b/sc/source/core/tool/interpr7.cxx
@@ -11,7 +11,100 @@
*/
#include "interpre.hxx"
+#include "libxml/xpath.h"
+
+#include <boost/shared_ptr.hpp>
// TODO: Add new methods for ScInterpreter here.
+void ScInterpreter::ScFilterXML()
+{
+ sal_uInt8 nParamCount = GetByte();
+ if (MustHaveParamCount( nParamCount, 2 ) )
+ {
+ OUString aXPathExpression = GetString();
+ OUString aString = GetString();
+
+ const char* pXPathExpr = OUStringToOString( aXPathExpression, RTL_TEXTENCODING_UTF8 ).getStr();
+ const char* pXML = OUStringToOString( aString, RTL_TEXTENCODING_UTF8 ).getStr();
+
+ boost::shared_ptr<xmlParserCtxt> pContext(
+ xmlNewParserCtxt(), xmlFreeParserCtxt );
+
+ boost::shared_ptr<xmlDoc> pDoc( xmlParseMemory( pXML, aString.getLength() ),
+ xmlFreeDoc );
+
+
+ boost::shared_ptr<xmlXPathContext> pXPathCtx( xmlXPathNewContext(pDoc.get()),
+ xmlXPathFreeContext );
+
+ boost::shared_ptr<xmlXPathObject> pXPathObj( xmlXPathEvalExpression(BAD_CAST(pXPathExpr), pXPathCtx.get()),
+ xmlXPathFreeObject );
+
+ switch(pXPathObj->type)
+ {
+ case XPATH_UNDEFINED:
+ break;
+ case XPATH_NODESET:
+ {
+ xmlNodeSetPtr pNodeSet = pXPathObj->nodesetval;
+ size_t nSize = pNodeSet->nodeNr;
+ if( nSize >= 1 )
+ {
+ if(pNodeSet->nodeTab[0]->type == XML_NAMESPACE_DECL)
+ {
+ xmlNsPtr ns = (xmlNsPtr)pNodeSet->nodeTab[0];
+ xmlNodePtr cur = (xmlNodePtr)ns->next;
+ boost::shared_ptr<xmlChar> pChar2(xmlNodeGetContent(cur), xmlFree);
+ OUString aResult = OUString::createFromAscii((char*)pChar2.get());
+ PushString(aResult);
+ }
+ else if(pNodeSet->nodeTab[0]->type == XML_ELEMENT_NODE)
+ {
+ xmlNodePtr cur = pNodeSet->nodeTab[0];
+ boost::shared_ptr<xmlChar> pChar2(xmlNodeGetContent(cur), xmlFree);
+ OUString aResult = OUString::createFromAscii((char*)pChar2.get());
+ PushString(aResult);
+ }
+ else
+ {
+ xmlNodePtr cur = pNodeSet->nodeTab[0];
+ boost::shared_ptr<xmlChar> pChar2(xmlNodeGetContent(cur), xmlFree);
+ OUString aResult = OUString::createFromAscii((char*)pChar2.get());
+ PushString(aResult);
+ }
+ }
+ }
+ break;
+ case XPATH_BOOLEAN:
+ assert(false);
+ break;
+ case XPATH_NUMBER:
+ assert(false);
+ break;
+ case XPATH_STRING:
+ assert(false);
+ break;
+ case XPATH_POINT:
+ assert(false);
+ break;
+ case XPATH_RANGE:
+ assert(false);
+ break;
+ case XPATH_LOCATIONSET:
+ assert(false);
+ break;
+ case XPATH_USERS:
+ assert(false);
+ break;
+ case XPATH_XSLT_TREE:
+ assert(false);
+ break;
+
+ }
+
+ }
+
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/src/scfuncs.src b/sc/source/ui/src/scfuncs.src
index 87b9cdd70f8f..702abcde07be 100644
--- a/sc/source/ui/src/scfuncs.src
+++ b/sc/source/ui/src/scfuncs.src
@@ -9730,6 +9730,36 @@ Resource RID_SC_FUNCTION_DESCRIPTIONS2
String 7 // Description of Parameter 3
{
Text [ en-US ] = "The number of characters for the text." ;
+ }
+ Resource SC_OPCODE_FILTERXML
+ {
+ ExtraData =
+ {
+ 0;
+ ID_FUNCTION_GRP_TEXT;
+ U2S( HID_FUNC_BITLSHIFT );
+ 2; 0; 0;
+ 0;
+ }
+ String 1 // Description
+ {
+ Text [ en-US ] = "Apply an XPath expression to an XML document";
+ };
+ String 2 // Name of Parameter 1
+ {
+ Text [ en-US ] = "XML Document";
+ };
+ String 3 // Description of Parameter 1
+ {
+ Text [ en-US ] = "String containing a valid XML stream";
+ };
+ String 4 // Name of parameter 2
+ {
+ Text [ en-US ] = "XPath expression";
+ };
+ String 5 // Description of Parameter 2
+ {
+ Text [ en-US ] = "String containing a valid XPath expression";
};
};
};