2009-11-05 4 views
4

J'ai écrit une fonction C++ wrapper pour libxml2 qui le rend facile pour moi de faire des requêtes sur un document XML:Quel est le moyen le plus efficace de faire des requêtes XPath récursives en utilisant libxml2?

bool XPathQuery(
    const std::string& doc, 
    const std::string& query, 
    XPathResults& results); 

Mais j'ai un problème: je dois pouvoir faire une autre requête XPath sur les résultats de ma première requête.

Actuellement je le fais en stockant le sous-document entier dans mon objet XPathResult, puis je passe XPathResult.subdoc dans la fonction XPathQuery. C'est terriblement inefficace. Donc, je me demande ... est-ce que libxml2 fournit quelque chose qui faciliterait le stockage du contexte d'une requête xpath (une référence à un noeud, peut-être?), Puis exécute une autre requête en utilisant cette référence comme xpath racine?

Répondre

5

Vous devriez réutiliser le xmlXPathContext et simplement changer son membre node.

#include <stdio.h> 
#include <libxml/xpath.h> 
#include <libxml/xmlerror.h> 

static xmlChar buffer[] = 
"<?xml version=\"1.0\"?>\n<foo><bar><baz/></bar></foo>\n"; 

int 
main() 
{ 
    const char *expr = "/foo"; 

    xmlDocPtr document = xmlReadDoc(buffer,NULL,NULL,XML_PARSE_COMPACT); 
    xmlXPathContextPtr ctx = xmlXPathNewContext(document); 
    //ctx->node = xmlDocGetRootElement(document); 

    xmlXPathCompExprPtr p = xmlXPathCtxtCompile(ctx, (xmlChar *)expr); 
    xmlXPathObjectPtr res = xmlXPathCompiledEval(p, ctx); 

    if (XPATH_NODESET != res->type) 
    return 1; 

    fprintf(stderr, "Got object from first query:\n"); 
    xmlXPathDebugDumpObject(stdout, res, 0); 
    xmlNodeSetPtr ns = res->nodesetval; 
    if (!ns->nodeNr) 
    return 1; 
    ctx->node = ns->nodeTab[0]; 
    xmlXPathFreeObject(res); 

    expr = "bar/baz"; 
    p = xmlXPathCtxtCompile(ctx, (xmlChar *)expr); 
    res = xmlXPathCompiledEval(p, ctx); 

    if (XPATH_NODESET != res->type) 
    return 1; 
    ns = res->nodesetval; 
    if (!ns->nodeNr) 
    return 1; 
    fprintf(stderr, "Got object from second query:\n"); 
    xmlXPathDebugDumpObject(stdout, res, 0); 

    xmlXPathFreeContext(ctx); 
    return 0; 
} 
+0

Ce programme se bloque de test pour moi quand il essaie de debugprint l'objet xmlxpath: xmlXPathDebugDumpObject (stdout, res, 0); Je vais voir si je ne peux pas comprendre ce qui se passe ... –

+0

On dirait que cela a quelque chose à voir avec la façon dont je construis ou reliant libxml2.dll. Bizarre. Quoi qu'il en soit, a travaillé autour d'elle. –

+0

C'est ce que je cherchais. Merci. =) –

Questions connexes