예제 #1
0
void XMLSubstitute::substitute( xmlNodePtr original, xmlNodePtr substitutionRules, std::map< std::string, std::string> &dictionary)
{
    std::list< ::fwRuntime::io::Substitute > substitutions = getSubstitutions( substitutionRules );

    for ( std::list< ::fwRuntime::io::Substitute >::iterator iter = substitutions.begin(); iter != substitutions.end(); ++iter )
    {
        std::string xpath = iter->xpath;
        std::string dictEntry = iter->dictEntry;
        std::string status = iter->status;
        bool entryInDictionary = dictionary.find(dictEntry) != dictionary.end();

        if ( status=="required" && !entryInDictionary )
        {
            OSLM_FATAL("XML substitution required dictEntry [" << dictEntry << "] missing for xpath " << xpath );
        }
        // optional and not in dictionary
        if ( status=="optional" && !entryInDictionary )
        {
            OSLM_INFO("XML substitution optional dictEntry [" << dictEntry << "] not modified for xpath " << xpath );
            continue;
        }

        OSLM_INFO("XML substitution dictEntry [" << dictEntry << "] modified with xpath " << xpath << " with the value : " <<  dictionary[dictEntry] );

        // create the context for xpath
        xmlXPathContextPtr xpathCtx;
        xpathCtx = xmlXPathNewContext(original->doc);
        SLM_ASSERT("xpathCtx not instanced", xpathCtx);
        // search
        xmlChar *xpathExpr= BAD_CAST xpath.c_str();
        xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression(xpathExpr, xpathCtx);
        SLM_ASSERT("xpathObj not instanced", xpathObj);

        int NbNodesFound = xpathObj->nodesetval->nodeNr;
        for (int i=NbNodesFound-1; i >= 0; --i )
        {
            xmlNodePtr node = xpathObj->nodesetval->nodeTab[i];
            // substitution
            if (node->type == XML_ATTRIBUTE_NODE )
            {
                xmlSetProp( node->parent, node->name, BAD_CAST dictionary[dictEntry].c_str() );
            }
            if (node->type == XML_ELEMENT_NODE )
            {
                xmlNodeSetName( node , BAD_CAST dictionary[dictEntry].c_str() );
            }
            if (node->type == XML_TEXT_NODE )
            {
                xmlNodeSetContent( node , BAD_CAST dictionary[dictEntry].c_str() );
            }
        }
        xmlXPathFreeObject(xpathObj );
    }
}
예제 #2
0
GenericAnswer* SchemaQueryHandler::handleQuery(Query* query) {
    const uint8_t max_depth = query->max_depth;
    const uint32_t max_total = query->attrResultMaxSize;

    MeaningDictionary dict;
    // using a HarvestEncoder to be able to fill
    // the MeaningDictonary on the fly, so we don't require an index for ids
    HarvestEncoder encoder(&dict);
    vector<EncodedFormula> exprs;
    exprs.reserve(query->tokens.size());

    vector<const CmmlToken*> exprsTokens;
    exprsTokens.reserve(query->tokens.size());
    for (const CmmlToken* tok : query->tokens) {
        EncodedFormula encTok;
        if (encoder.encode(_encodingConfig, tok, &encTok, nullptr) == 0) {
            exprs.push_back(std::move(encTok));
            exprsTokens.push_back(tok);
        }
    }

    SchemaEngine::Config engineConfig;
    switch (query->cutoff_mode) {
    case 'A':
        engineConfig.cutoffHeuristic = SchemaEngine::ABSOLUTE;
        break;
    case 'R':
        engineConfig.cutoffHeuristic = SchemaEngine::RELATIVE;
        break;
    default:
        PRINT_WARN("Invalid cutoff heuristic %c\n. Using default.",
                   query->cutoff_mode);
        engineConfig.cutoffHeuristic = SchemaEngine::ABSOLUTE;  // default
        break;
    }

    SchemaEngine schemaEngine(dict, engineConfig);
    SchemaAnswset* result =
        schemaEngine.getSchemata(exprs, exprsTokens, max_total, max_depth);

    /* we can't deduce the substitutions in SchemaEngine because we need
     * the original query, so we will do it here */
    for (ExprSchema& sch : result->schemata) {
        /* As a heuristic,
         * we choose the first formula in this class to be schematized */
        const uint32_t representativeId = sch.formulae.front();
        CmmlToken* exprRoot = query->tokens[representativeId];
        getSubstitutions(exprRoot, sch.root, &sch.subst);
    }

    return result;
}
예제 #3
0
void SchemaQueryHandler::getSubstitutions(CmmlToken* exprRoot,
                                          CmmlToken* schemaRoot,
                                          vector<string>* subst) {
    if (exprRoot == nullptr || schemaRoot == nullptr || subst == nullptr) {
        PRINT_WARN("nullptr pased. Skipping...");
        return;
    }
    auto exprChildren = exprRoot->getChildNodes();
    auto schemaChildren = schemaRoot->getChildNodes();

    const string& currSchemaTag = schemaRoot->getTag();
    if (currSchemaTag == types::QVAR_TAG) {
        const string& xref = exprRoot->getAttribute("xref");
        if (xref == "") {
            PRINT_LOG("Missing href attribute. Skipping...");
            return;
        }
        subst->push_back(xref);
        return;
    }

    if (exprChildren.size() != schemaChildren.size()) {
        PRINT_WARN("Expression and schema are incompatible. Skipping...");
        return;
    }

    auto expr_it = exprChildren.begin();
    auto schema_it = schemaChildren.begin();
    const string& currExprTag = exprRoot->getTag();
    if (currExprTag != currSchemaTag) {
        PRINT_WARN("Expression and schema are incompatible. Skipping...");
        return;
    }
    // Done with this token?
    if (exprChildren.size() == 0) {
        return;
    }

    // disregard the first child of apply
    if (currExprTag == "apply") {
        expr_it++;
        schema_it++;
    }

    /* we know that both exprChildren and schemaChildren have the same length,
     * so it is enough to check for one */
    while (expr_it != exprChildren.end()) {
        getSubstitutions(*expr_it, *schema_it, subst);
        ++expr_it;
        ++schema_it;
    }
}