#include "../config/pathan_config.h" /* * Copyright (c) 2001, DecisionSoft Limited All rights reserved. * Please see LICENSE.TXT for more information. */ #include #include #include #include #include #include #include #include #include const XMLCh FunctionTokenize::name[] = { XERCES_CPP_NAMESPACE_QUALIFIER chLatin_t, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_o, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_k, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_e, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_n, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_i, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_z, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_e, XERCES_CPP_NAMESPACE_QUALIFIER chNull }; /** * fn:tokenize($input as xs:string?, $pattern as xs:string) as xs:string+ * fn:tokenize($input as xs:string?, $pattern as xs:string, $flags as xs:string) as xs:string+ */ FunctionTokenize::FunctionTokenize(const VectorOfDataItems &args, XPath2MemoryManager* memMgr) : ConstantFoldingFunction(name,2, 3, "string?, string, string", args, memMgr) { } Sequence FunctionTokenize::collapseTreeInternal(DynamicContext* context, int flags) const { XPath2MemoryManager* memMgr = context->getMemoryManager(); Sequence inputString=getParamNumber(1,context); Sequence patternString=getParamNumber(2,context); // If the value of $operand1 is the empty sequence, the empty sequence is returned. if(inputString.isEmpty()) return Sequence(DatatypeFactory::STR2AT::createString(memMgr, XERCES_CPP_NAMESPACE_QUALIFIER XMLUni::fgZeroLenString, context), memMgr); const XMLCh *input=((const ATStringOrDerived*)inputString.first())->asString(context); const XMLCh *pattern=((const ATStringOrDerived*)patternString.first())->asString(context); const XMLCh *options = XERCES_CPP_NAMESPACE_QUALIFIER XMLUni::fgZeroLenString; if(getNumArgs()>2) options=getParamNumber(3,context).castAsSingleString(context); //Check that the options are valid - throw an exception if not (can have s,m,i and x) //Note: Are allowed to duplicate the letters. unsigned int i; for (i=0; i< XERCES_CPP_NAMESPACE_QUALIFIER XMLString::stringLen(options); i ++){ if (options[i]!= XERCES_CPP_NAMESPACE_QUALIFIER chLatin_s && options[i]!= XERCES_CPP_NAMESPACE_QUALIFIER chLatin_m && options[i]!= XERCES_CPP_NAMESPACE_QUALIFIER chLatin_i && options[i]!= XERCES_CPP_NAMESPACE_QUALIFIER chLatin_x) DSLthrow(FunctionException, X("FunctionTokenize::collapseTreeInternal"),X("Invalid regular expression flags")); } //Now attempt to tokenize XERCES_CPP_NAMESPACE_QUALIFIER RefArrayVectorOf* toks=NULL; try { XERCES_CPP_NAMESPACE_QUALIFIER RegularExpression regEx(pattern, options, memMgr); toks = regEx.tokenize(input); } catch (XERCES_CPP_NAMESPACE_QUALIFIER XMLException &e){ //REVISIT: when this error goes back in xerces, add this back /* if (e.getCode() == XERCES_CPP_NAMESPACE_QUALIFIER XMLExcepts::Regex_TokPatMatchesZeroString){ DSLthrow(FunctionException, X("FunctionTokenize::collapseTreeInternal"),X("Pattern matches zero-length string")); } else */ throw; } catch (...){ DSLthrow(FunctionException, X("FunctionTokenize::collapseTreeInternal"),X("Invalid regular expression")); } Sequence resultSeq(toks -> size(),memMgr); for (i = 0; i < toks -> size(); i++){ resultSeq.addItem(DatatypeFactory::STR2AT::createString(memMgr, toks -> elementAt(i), context)); } return resultSeq; }