#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 #include // defines X() and XMLCh* #include #include const XMLCh FunctionLang::name[] = { XERCES_CPP_NAMESPACE_QUALIFIER chLatin_l, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_a, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_n, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_g, XERCES_CPP_NAMESPACE_QUALIFIER chNull }; /** * fn:lang($testlang as xs:string?) as xs:boolean **/ FunctionLang::FunctionLang(const VectorOfDataItems &args, XPath2MemoryManager* memMgr) : DataItemFunction(name,1, 1, "string?", args, memMgr) { } DataItem* FunctionLang::staticResolution(StaticContext *context, StaticResolutionContext *src) { src->contextItemUsed(true); return resolveDataItems(_args, context, src, false); } Sequence FunctionLang::collapseTreeInternal(DynamicContext* context, int flags) const { XPath2MemoryManager* memMgr = context->getMemoryManager(); Sequence arg1=getParamNumber(1, context); const XMLCh *param1 = XERCES_CPP_NAMESPACE_QUALIFIER XMLUni::fgZeroLenString; if(!arg1.isEmpty()) param1=((const ATStringOrDerived*)arg1.first())->asString(context); const XMLCh* xmlLangValue = XPath2Utils::toLower(param1, context->getMemoryManager()); bool isSubLang = XERCES_CPP_NAMESPACE_QUALIFIER XMLString::indexOf(xmlLangValue, XERCES_CPP_NAMESPACE_QUALIFIER chDash) > 0; const XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *contextNode=0; const Item *item = context->getContextItem(); if(item!=NULL && item->isNode()) contextNode= ((const Node*)item)->getDOMNode(); if(contextNode==0) return Sequence(DatatypeFactory::POD2AT::createBoolean(memMgr, false, context), memMgr); XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* root = contextNode->getOwnerDocument(); static const XMLCh xmlLang[] = { XERCES_CPP_NAMESPACE_QUALIFIER chLatin_l, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_a, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_n, XERCES_CPP_NAMESPACE_QUALIFIER chLatin_g, XERCES_CPP_NAMESPACE_QUALIFIER chNull}; static const XMLCh* xmlLangNamespace = XERCES_CPP_NAMESPACE_QUALIFIER XMLUni::fgXMLURIName; const XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* node=contextNode; if(contextNode->getNodeType()!=XERCES_CPP_NAMESPACE_QUALIFIER DOMNode::ELEMENT_NODE) if(contextNode->getNodeType()==XERCES_CPP_NAMESPACE_QUALIFIER DOMNode::ATTRIBUTE_NODE) node=static_cast(contextNode)->getOwnerElement(); else node=node->getParentNode(); while(node != 0 && node != root) { const XERCES_CPP_NAMESPACE_QUALIFIER DOMElement* element=static_cast(node); const XMLCh * value = element->getAttributeNS(xmlLangNamespace, xmlLang); if(XERCES_CPP_NAMESPACE_QUALIFIER XMLString::stringLen(value) != 0) { const XMLCh* asLower = XPath2Utils::toLower(value, context->getMemoryManager()); int dashLocation = XERCES_CPP_NAMESPACE_QUALIFIER XMLString::indexOf(asLower, XERCES_CPP_NAMESPACE_QUALIFIER chDash); if(dashLocation!=-1 && !isSubLang) { asLower = XPath2Utils::subString(asLower, 0, dashLocation, memMgr); } return Sequence(DatatypeFactory::POD2AT::createBoolean(memMgr, XPath2Utils::equals(asLower, xmlLangValue), context), memMgr); } node = node->getParentNode(); } return Sequence(DatatypeFactory::POD2AT::createBoolean(memMgr, false, context), memMgr); }