名称空间和xpath的libxml2错误

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

#include  #include  #include  #include  #include  xmlDocPtr getdoc (char *docname) { xmlDocPtr doc; doc = xmlParseFile(docname); if (doc == NULL ) { fprintf(stderr,"Document not parsed successfully. \n"); return NULL; } return doc; } xmlXPathObjectPtr getnodeset (xmlDocPtr doc, xmlChar *xpath){ xmlXPathContextPtr context; xmlXPathObjectPtr result; context = xmlXPathNewContext(doc); if (context == NULL) { printf("Error in xmlXPathNewContext\n"); 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\n"); return NULL; } if(xmlXPathNodeSetIsEmpty(result->nodesetval)){ xmlXPathFreeObject(result); printf("No result\n"); 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 nodesetval; for (i=0; i nodeNr; i++) { keyword = xmlNodeListGetString(doc, nodeset->nodeTab[i]->xmlChildrenNode, 1); printf("keyword: %s\n", keyword); xmlFree(keyword); } xmlXPathFreeObject (result); } xmlFreeDoc(doc); xmlCleanupParser(); return (1); } 

我的问题是我想解析以下的xml

   Sec_1 Sec_2  

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

我假设我的代码失败,因为我没有正确使用名称空间前缀。 我没时间了。 能否请你帮忙?

事实certificate,正如我从这里发现的那样,它并不是libXml的失败,这是一个问题,因为libXml 正确遵循XML / XPATH规范。

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

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

 xmlXPathRegisterNs(context, BAD_CAST "new", BAD_CAST "http://www.example.com/new" xmlChar *xpath = (xmlChar*) "/new:book/new:section1"; 

我在这里列出了xml的可见性:

   Sec_1 Sec_2  

这是libXml库的恼人故障。 如cateof所述,问题是默认的名称空间声明:

的xmlns = “http://www.example.com/new”

两种选择:
(1)在书签中删除该声明或(2)为其命名,并在标签中使用该名称。

例如

的xmlns:新= “http://www.example.com/new”

然后你的标签看起来像:

new:book new:section1

等等。

这是默认命名空间的问题。 要匹配您需要的路径/ new:tag / new:tag等