名称空间和 xpath 的 libxml2 错误 [英] libxml2 error with namespaces and xpath

查看:12
本文介绍了名称空间和 xpath 的 libxml2 错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在这里粘贴一些代码,使用 gcc file.c -lxml2 编译时没有警告,假设您的系统中安装了 libxml2.

I am pasting some code here that compiles with no warning using gcc file.c -lxml2, assuming that libxml2 is installed in your system.

#include <libxml/parser.h>
#include <libxml/xpath.h>
#include <assert.h>
#include <libxml/tree.h>
#include <libxml/xpathInternals.h>

xmlDocPtr
getdoc (char *docname) {
    xmlDocPtr doc;
    doc = xmlParseFile(docname);

    if (doc == NULL ) {
        fprintf(stderr,"Document not parsed successfully. 
");
        return NULL;
    }

    return doc;
}

xmlXPathObjectPtr
getnodeset (xmlDocPtr doc, xmlChar *xpath){

    xmlXPathContextPtr context;
    xmlXPathObjectPtr result;

    context = xmlXPathNewContext(doc);
    if (context == NULL) {
        printf("Error in xmlXPathNewContext
");
        return NULL;
    }

    if(xmlXPathRegisterNs(context,  BAD_CAST "new", BAD_CAST "http://www.example.com/new") != 0) {
        fprintf(stderr,"Error: unable to register NS with prefix");
        return NULL;
    }

    result = xmlXPathEvalExpression(xpath, context);
    xmlXPathFreeContext(context);
    if (result == NULL) {
        printf("Error in xmlXPathEvalExpression
");
        return NULL;
    }
    if(xmlXPathNodeSetIsEmpty(result->nodesetval)){
        xmlXPathFreeObject(result);
                printf("No result
");
        return NULL;
    }
    return result;
}

int
main(int argc, char **argv) {

    char *docname;
    xmlDocPtr doc;
    xmlChar *xpath = (xmlChar*) "/new:book/section1";
    xmlNodeSetPtr nodeset;
    xmlXPathObjectPtr result;
    int i;
    xmlChar *keyword;

    if (argc <= 1) {
        printf("Usage: %s docname
", argv[0]);
        return(0);
    }

    docname = argv[1];
    doc = getdoc(docname);
    result = getnodeset (doc, xpath);
    if (result) {
        nodeset = result->nodesetval;
        for (i=0; i < nodeset->nodeNr; i++) {
            keyword = xmlNodeListGetString(doc, nodeset->nodeTab[i]->xmlChildrenNode, 1);
        printf("keyword: %s
", keyword);
        xmlFree(keyword);
        }
        xmlXPathFreeObject (result);
    }

    xmlFreeDoc(doc);
    xmlCleanupParser();
    return (1);
}

我的问题是我要解析下面的xml

My problem is that I want to parse the following xml

<?xml version="1.0" encoding="UTF-8"?>
<book xmlns="http://www.example.com/new">
    <section1>Sec_1</section1>
    <section2>Sec_2</section2>
</book>

book 元素在该元素内定义了一个命名空间.我想打印 xpath/book/section1 中的值,它返回 NULL.当我尝试返回命名空间下的元素时,我也会收到错误,即/new:book/section1

the book element defines a namespace inside that element. I want to print the value in the xpath /book/section1 and it returns NULL. When I am trying to return the element under a namespace I also get errors, ie /new:book/section1

我假设我的代码失败是因为我没有正确使用命名空间前缀.我没时间了.你能帮忙吗?

I assume that my code fails because I am not using correctly the namespace prefixes. I run out of time. Could you please help?

推荐答案

结果,正如我从 这里,这并不是 libXml 的真正失败,而是一个问题,因为 libXml 正确 遵循 XML/XPATH 规范.

Turns out, as I found out from here, it is not really a failure of libXml, it's a problem because libXml correctly follows the XML/XPATH specifications.

R Bourdeau 提出的解决方案是正确的,但是,如果您可以控制正在解析的 xml 文档.

The solutions proposed by R Bourdeau are correct, however, if you have control of the xml document you are parsing.

XPATH 查询的上下文独立于 xml 文档中的命名空间限定符.默认命名空间强制所有子标签进入一个命名空间;它们不需要在文档中进行限定,但必须在 xpath 查询中进行限定.幸运的是,您使用 libXml 将命名空间注册为 new,因此 cateof 的解决方案应该可以工作.

The context for the XPATH query is independent of the namespace qualifiers in the xml document. The default namespace forces all child tags into a namespace; they don't require qualification in the document but must be qualified in the xpath query. Fortunately, you registered the namespace as new with libXml, so cateof's solution should work.

xmlXPathRegisterNs(context,  BAD_CAST "new", BAD_CAST "http://www.example.com/new"

xmlChar *xpath = (xmlChar*) "/new:book/new:section1";

我在这里内联 xml 以提高可见性:

I'm inlining the xml here for visibility:

<?xml version="1.0" encoding="UTF-8"?>
<book xmlns="http://www.example.com/new">
    <section1>Sec_1</section1>
    <section2>Sec_2</section2>
</book>

这篇关于名称空间和 xpath 的 libxml2 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆