Ejemplo n.º 1
0
  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 ();
      }
  }