コード例 #1
0
/*
 * call-seq:
 *  register_variable(name, value)
 *
 * Register the variable +name+ with +value+.
 */
static VALUE register_variable(VALUE self, VALUE name, VALUE value)
{
   xmlXPathContextPtr ctx;
   xmlXPathObjectPtr xmlValue;
   Data_Get_Struct(self, xmlXPathContext, ctx);

   xmlValue = xmlXPathNewCString(StringValuePtr(value));

   xmlXPathRegisterVariable( ctx,
      (const xmlChar *)StringValuePtr(name),
      xmlValue
   );

   return self;
}
コード例 #2
0
ファイル: xml_edit.c プロジェクト: cczurda/xmlstar
/**
 *  Loop through array of operations and perform them
 */
static void
edProcess(xmlDocPtr doc, const XmlEdAction* ops, int ops_count)
{
    int k;
    xmlXPathContextPtr ctxt = xmlXPathNewContext(doc);
    /* NOTE: later registrations override earlier ones */
    registerXstarNs(ctxt);

    /* variables */
    previous_insertion = xmlXPathNodeSetCreate(NULL);
    registerXstarVariable(ctxt, "prev",
        xmlXPathWrapNodeSet(previous_insertion));
    xmlDeregisterNodeDefault(&removeNodeFromPrev);

#if HAVE_EXSLT_XPATH_REGISTER
    /* register extension functions */
    exsltDateXpathCtxtRegister(ctxt, BAD_CAST "date");
    exsltMathXpathCtxtRegister(ctxt, BAD_CAST "math");
    exsltSetsXpathCtxtRegister(ctxt, BAD_CAST "set");
    exsltStrXpathCtxtRegister(ctxt, BAD_CAST "str");
#endif
    /* namespaces from doc */
    extract_ns_defs(doc, ctxt);
    /* namespaces from command line */
    nsarr_xpath_register(ctxt);

    for (k = 0; k < ops_count; k++)
    {
        xmlXPathObjectPtr res;
        xmlNodeSetPtr nodes;

        /* NOTE: to make relative paths match as if from "/", set context to
           document; setting to root would match as if from "/node()/" */
        ctxt->node = (xmlNodePtr) doc;

        if (ops[k].op == XML_ED_VAR) {
            res = xmlXPathEvalExpression(BAD_CAST ops[k].arg2, ctxt);
            xmlXPathRegisterVariable(ctxt, BAD_CAST ops[k].arg1, res);
            continue;
        }

        res = xmlXPathEvalExpression(BAD_CAST ops[k].arg1, ctxt);
        if (!res || res->type != XPATH_NODESET || !res->nodesetval) continue;
        nodes = res->nodesetval;

        switch (ops[k].op)
        {
            case XML_ED_DELETE:
                edDelete(doc, nodes);
                break;
            case XML_ED_MOVE: {
                xmlXPathObjectPtr res_to;
                ctxt->node = (xmlNodePtr) doc;
                res_to = xmlXPathEvalExpression(BAD_CAST ops[k].arg2, ctxt);
                if (!res_to
                    || res_to->type != XPATH_NODESET
                    || res_to->nodesetval->nodeNr != 1) {
                    fprintf(stderr, "move destination is not a single node\n");
                    continue;
                }
                edMove(doc, nodes, res_to->nodesetval->nodeTab[0]);
                xmlXPathFreeObject(res_to);
                break;
            }
            case XML_ED_UPDATE:
                edUpdate(doc, nodes, ops[k].arg2, ops[k].type, ctxt);
                break;
            case XML_ED_RENAME:
                edRename(doc, nodes, ops[k].arg2, ops[k].type);
                break;
            case XML_ED_INSERT:
                edInsert(doc, nodes, ops[k].arg2, ops[k].arg3, ops[k].type, -1);
                break;
            case XML_ED_APPEND:
                edInsert(doc, nodes, ops[k].arg2, ops[k].arg3, ops[k].type, 1);
                break;
            case XML_ED_SUBNODE:
                edInsert(doc, nodes, ops[k].arg2, ops[k].arg3, ops[k].type, 0);
                break;
            default:
                break;
        }
        xmlXPathFreeObject(res);
    }
    /* NOTE: free()ing ctxt also free()s previous_insertion */
    previous_insertion = NULL;
    xmlDeregisterNodeDefault(NULL);

    xmlXPathFreeContext(ctxt);
}