xpath表达式中的libxml2谓词并不总是被识别

时间:2013-06-20 15:12:46

标签: xpath libxml2 predicates

我呼吁你,因为我在使用不考虑xpath表达式中某些参数的libxml2库时遇到了问题。

以下是我尝试解析的xml文件示例:

<?xml version="1.0" encoding="ISO-8859-1"?>

<bookstore>

    <book title="Harry Potter" lang="eng" version="1">
       <price>29.99</price>
    </book>

    <book title="Learning XML" lang="eng" version="2">
        <price>38.95</price>
    </book>

    <book title="Learning C" lang="eng" version="2">  
       <price>39.95</price>
    </book>

</bookstore>

假设我要提取所有母语为英语且版本为第一版的书籍。

如果我没弄错以下XPath表达式,我会使用:

//book[@lang='eng' and @version='1']

以及我的代码中的以下说明:

xmlChar * xpath_expression = "//book[@lang='eng' and @version='1']";
xmlXPathObjectPtr xpathRes = xmlXPathEvalExpression(xpath_expression, ctxt);

问题在于,我得到了书籍清单,好像我只是做了以下请求:

//book

我想知道我的版本是否有错误,知道我的debian挤压(2.7.8.dfsg-2 + squeeze7)最新...

1 个答案:

答案 0 :(得分:0)

这肯定不是libxml2中的错误。你可能在其他地方犯了错误。以下代码仅打印“哈利波特”:

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

int main()
{
    static const char xml[] =
        "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n"
        "<bookstore>\n"
        "    <book title=\"Harry Potter\" lang=\"eng\" version=\"1\">\n"
        "       <price>29.99</price>\n"
        "    </book>\n"
        "    <book title=\"Learning XML\" lang=\"eng\" version=\"2\">\n"
        "        <price>38.95</price>\n"
        "    </book>\n"
        "    <book title=\"Learning C\" lang=\"eng\" version=\"2\">  \n"
        "       <price>39.95</price>\n"
        "    </book>\n"
        "</bookstore>\n";

    xmlDocPtr doc = xmlParseMemory(xml, sizeof(xml));
    xmlXPathContextPtr ctxt = xmlXPathNewContext(doc);
    xmlChar *expression = BAD_CAST "//book[@lang='eng' and @version='1']";
    xmlXPathObjectPtr res = xmlXPathEvalExpression(expression, ctxt);
    xmlNodeSetPtr nodeset = res->nodesetval;

    for (int i = 0; i < nodeset->nodeNr; i++) {
        xmlNodePtr node = nodeset->nodeTab[i];
        xmlChar *title = xmlGetProp(node, BAD_CAST "title");
        printf("%s\n", title);
    }   

    xmlXPathFreeObject(res);
    xmlXPathFreeContext(ctxt);
    xmlFreeDoc(doc);

    return 0;
}