#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 FunctionReplace::name[] = { XERCES_CPP_NAMESPACE_QUALIFIER chLatin_r, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_e, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_p, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_l, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_a, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_c, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_e, XERCES_CPP_NAMESPACE_QUALIFIER chNull }; /** * fn:replace($input as xs:string?, $pattern as xs:string, $replacement as xs:string) as xs:string * fn:replace($input as xs:string?, $pattern as xs:string, $replacement as xs:string, $flags as xs:string) as xs:string */ FunctionReplace::FunctionReplace(const VectorOfDataItems &args, XPath2MemoryManager* memMgr) : ConstantFoldingFunction(name,3, 4, "string?, string, string, string", args, memMgr) { } Sequence FunctionReplace::collapseTreeInternal(DynamicContext* context, int flags) const { XPath2MemoryManager* memMgr = context->getMemoryManager(); Sequence inputString=getParamNumber(1,context); Sequence patternString=getParamNumber(2,context); Sequence replacementString=getParamNumber(3,context); const XMLCh* input = XERCES_CPP_NAMESPACE_QUALIFIER XMLUni::fgZeroLenString; if(!inputString.isEmpty()) input=((const ATStringOrDerived*)inputString.first())->asString(context); const XMLCh *pattern = ((const ATStringOrDerived*)patternString.first())->asString(context); const XMLCh *replacement = ((const ATStringOrDerived*)replacementString.first())->asString(context); const XMLCh *options = XERCES_CPP_NAMESPACE_QUALIFIER XMLUni::fgZeroLenString; if(getNumArgs()>3) options=getParamNumber(4,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. for (unsigned int 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("FunctionReplace::collapseTreeInternal"),X("Invalid regular expression flags")); } const XMLCh* result=NULL; //Now attempt to replace try { XERCES_CPP_NAMESPACE_QUALIFIER RegularExpression regEx(pattern, options, memMgr); result = regEx.replace(input, replacement); } catch (XERCES_CPP_NAMESPACE_QUALIFIER XMLException &e){ if (e.getCode() == XERCES_CPP_NAMESPACE_QUALIFIER XMLExcepts::Regex_RepPatMatchesZeroString){ DSLthrow(FunctionException, X("FunctionReplace::collapseTreeInternal"),X("Regular expression matches zero-length string")); } else if (e.getCode() == XERCES_CPP_NAMESPACE_QUALIFIER XMLExcepts::Regex_InvalidRepPattern) { DSLthrow(FunctionException, X("FunctionReplace::collapseTreeInternal"),X("Invalid replacement string")); } else { throw; } } catch(...) { DSLthrow(FunctionException, X("FunctionReplace::collapseTreeInternal"),X("Invalid regular expression")); } return Sequence(DatatypeFactory::STR2AT::createString(memMgr, result, context), memMgr); }