2009-11-05 2 views
4

나는 나 XML 문서에 쿼리를 할 것이 용이하게하는 C++ libxml2를위한 래퍼 함수 작성했습니다 :libxml2를 사용하여 반복적 인 XPath 쿼리를 수행하는 가장 효율적인 방법은 무엇입니까?

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

을하지만 문제가 : 나는 다른 XPath 쿼리를 수행 할 수 있어야합니다 내 첫 번째 쿼리의 결과.

현재이 작업은 전체 하위 문서를 내 XPathResult 개체에 저장 한 다음 XPathResult.subdoc을 XPathQuery 함수로 전달합니다. 이것은 매우 비효율적입니다.

그래서 궁금한데 ... libxml2는 xpath 쿼리 (아마도 노드에 대한 참조)의 컨텍스트를 저장하고 해당 참조를 사용하여 다른 쿼리를 xpath로 쉽게 수행 할 수있는 기능을 제공합니까? 뿌리?

답변

5

xmlXPathContext을 다시 사용하고 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

이 테스트 프로그램는 xmlxpath 객체 debugprint하려고 나를 위해 충돌 : xmlXPathDebugDumpObject을 (표준 출력, 고해상도, 0); 내가 무슨 일이 일어나는지 알아낼 수 없다면 ... –

+0

libxml2.dll을 빌드하거나 연결하는 방법과 관련이있는 것 같습니다. 기묘한. 어쨌든, 주위에 일했다. –

+0

이것은 내가 찾고 있었던 것이다. 감사. =) –