void XPath::evalFunctionKeyGet ( ElementMultiMapRef& map, XPath& useXPath, NodeSet& resultNodeSet, String& value ) { __ui64 hash = SKMapRef::hashString ( value ); Log_EvalKey ( "Computed value : '%s', hash='%llx'\n", value.c_str(), hash ); for ( SKMultiMapRef::multi_iterator miter ( map, hash ); miter ; miter++ ) { Log_EvalKey ( "Found iter %llx, val=%llx\n", miter.getHash(), miter.getValue() ); if ( miter.getHash() != hash ) { Log_EvalKey ( "Diverging keys : %llx != %llx\n", miter.getHash(), hash ); break; } ElementRef foundElt = map.get ( miter ); Log_EvalKey ( "Found elt=0x%llx\n", foundElt.getElementId() ); // AssertBug ( foundElt.getElementId(), "Null elementId ! Element was deleted ?\n" ); NodeSet foundValue; useXPath.eval ( foundValue, foundElt ); for ( NodeSet::iterator valiter ( foundValue ) ; valiter ; valiter++ ) { String eltValue = valiter->toString(); Log_EvalKey ( "Found node 0x%llx:%s, eltValue='%s'\n", foundElt.getElementId(), foundElt.getKey().c_str(), eltValue.c_str() ); if ( eltValue == value ) { resultNodeSet.pushBack ( foundElt, true ); Log_EvalKey ( "Matches !\n" ); } } } }
static void xemInstructionSetDocument ( __XProcHandlerArgs__ ) { if ( ! item.hasAttr(xem.href() ) ) { throwXemProcessorException ( "Instruction xem:set-document has no attribute xem:href\n" ); } if ( ! item.hasAttr(xem.select() ) ) { throwXemProcessorException ( "Instruction xem:set-document has no attribute xem:select\n" ); } String href = item.getEvaledAttr ( xproc, currentNode, xem.href() ); XPath selectXPath ( item, xem.select() ); NodeSet document; selectXPath.eval ( xproc, document, currentNode ); if ( ! document.isScalar() ) { throwXemProcessorException ( "Instruction xem:set-document : xem:select '%s' returns a non-scalar result !\n", item.getAttr (xem.select() ).c_str() ); } if ( ! document.front().isElement() ) { throwXemProcessorException ( "Instruction xem:set-document : xem:select '%s' returns a non-element result !\n", item.getAttr (xem.select() ).c_str() ); } ElementRef rootDocument = document.front().toElement(); xproc.setDocument ( href, rootDocument ); }
void XPath::evalFunctionKeyBuild ( ElementRef& baseElement, ElementMultiMapRef& map, XPath& matchXPath, XPath& useXPath, XPath& scopeXPath, KeyId mapId ) { bool recursive = true; // Warn !! Log_EvalKey ( "evalFunctionKeyBuild(baseElement=%s, match=%s, use=%s, scope=%s\n", baseElement.getKey().c_str(), matchXPath.expression, useXPath.expression, scopeXPath.expression); if ( ! recursive ) { Warn ( "Building key in a non-recursive mode ! This is against XSL specifications !\n" ); } if ( ! baseElement.getChild() ) { Log_EvalKey ( "Base element has no children !\n" ); return; } ElementRef current = baseElement; Log_EvalKey ( "Building Key !\n" ); Log_EvalKey ( "baseElement = '%s'\n", baseElement.getKey().c_str() ); Log_EvalKey ( "baseElement = '%s'\n", baseElement.generateVersatileXPath().c_str() ); __ui64 iterated = 0, found = 0; bool currentMatches; while ( true ) { Log_EvalKey ( "[At element %s (0x%llx:%x/%s), matching '%s' ?\n", current.generateVersatileXPath().c_str(), current.getElementId(), current.getKeyId(), current.getKey().c_str(), matchXPath.expression ); currentMatches = false; iterated++; if ( matchXPath.matches ( current ) ) { Log_EvalKey ( "Matches !\n" ); currentMatches = true; found++; if ( map ) { map.insert ( current, useXPath ); } else { NodeSet scopeNodeSet; scopeXPath.eval ( scopeNodeSet, current ); if ( scopeNodeSet.size() == 1 && scopeNodeSet.front().isElement() ) { ElementRef scopeElement = scopeNodeSet.toElement(); ElementMultiMapRef currentMap = scopeElement.findAttr ( mapId, AttributeType_SKMap ); if ( ! currentMap ) { Info ( "New skMap at '%s'\n", scopeElement.generateVersatileXPath().c_str() ); currentMap = scopeElement.addSKMap ( mapId, SKMapType_ElementMultiMap ); } Log_EvalKey ( "Inserting '%s'\n", current.generateVersatileXPath().c_str() ); currentMap.insert ( current, useXPath ); } else { Info ( "Silently ignoring '%s' : scope did not eval to an Element.\n", current.generateVersatileXPath().c_str() ); } } } if ( current.getChild() && ( !currentMatches || recursive ) ) { Log_EvalKey ( "Don't match, but has children.\n" ); current = current.getChild(); continue; } else { Log_EvalKey ( "Don't match, but no has child.\n" ); } while ( ! current.getYounger() ) { AssertBug ( current != baseElement, "How did I get there ?\n" ); current = current.getFather(); if ( ! current ) { throwException ( Exception, "Preliminary end of element !\n" ); } AssertBug ( current, "current had no father !\n" ); if ( current == baseElement ) { Log_EvalKey ( "Indexing finished : iterated over %llu, found %llu.\n", iterated, found ); return; } } current = current.getYounger (); } }