c - libXML2 节点返回空

标签 c linux libxml2

我已经从项目中提取了这段代码(工作正常)。由于我不了解 libXMLXML 我找不到要解决的问题。 XML 文件位于 link

我得到输出:

Error: empty set as a result of evaluation xpath expression "/SOA/sehirler[0]/Bolge"
Error: empty set as a result of evaluation xpath expression "/SOA/sehirler[0]/Peryot"
Error: empty set as a result of evaluation xpath expression "/SOA/sehirler[0]/İli"
Error: empty set as a result of evaluation xpath expression "/SOA/sehirler[0]/Durum"
Error: empty set as a result of evaluation xpath expression "/SOA/sehirler[0]/Mak"
Segmentation fault

而不是仅仅获取

İstanbul

在控制台输出中。

可以用这个编译

gcc -Wall main.c -o out $(pkg-config --cflags --libs glib-2.0 libxml-2.0)

以下是要粘贴到 main.c 中的工作代码

#include <glib-2.0/glib.h>

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

typedef struct weatherXmlSourceNode {
  char *bolge, *peryot, *ili, *durum;
  int mak;
} weatherSource;
weatherSource *wsrc[6];

xmlDocPtr doc;

char *grabNodeFromFile(xmlDocPtr xml_doc, char* nodeName, int item_index) {
  char xpath[64];
  xmlXPathContextPtr xpathCtx; 
  xmlXPathObjectPtr xpathObj; 
  xmlNodeSetPtr nodeset;

  sprintf(xpath, "/SOA/sehirler[%d]/%s",item_index,nodeName);

  xpathCtx = xmlXPathNewContext(xml_doc);

  if(xpathCtx == NULL) {
    fprintf(stderr,"Error: unable to create new XPath context\n");
    return(NULL);
  }

  /* Evaluate xpath expression */
  xpathObj = xmlXPathEvalExpression((xmlChar *)xpath, xpathCtx);
  xmlXPathFreeContext(xpathCtx);
  if(xpathObj == NULL) {
    fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", xpath);
    return(NULL);
  }

  /* Check if xmlXPathEvalExpression had returned nonempty nodeset*/
  if (xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) {
    fprintf(stderr,"Error: empty set as a result of evaluation xpath expression \"%s\"",xpath);
    xmlXPathFreeObject (xpathObj);
    return(NULL);
  }

  nodeset = xpathObj->nodesetval;

  //there should be only one node in nodeset. So we return contents of the first node in nodeset
  return (char *)xmlNodeListGetString(xml_doc, nodeset->nodeTab[0]->xmlChildrenNode,1);
}

void fill_entry_from_rss(weatherSource *wsrc, xmlDocPtr filename, int doc_index) {
  /* Fill respective elements */
  wsrc->bolge = grabNodeFromFile(filename, "Bolge", doc_index);
  wsrc->peryot = grabNodeFromFile(filename, "Peryot", doc_index);
  wsrc->ili = grabNodeFromFile(filename, "İli", doc_index);
  wsrc->durum = grabNodeFromFile(filename, "Durum", doc_index);
  wsrc->mak = grabNodeFromFile(filename, "Mak", doc_index);
}

int fill_entry_from_rss_loop() {
  //int doc_item_index = 1;
  /* Load XML documents */
  doc = xmlParseFile("sonSOA.xml");
  if (doc == NULL) {
    fprintf(stderr, "Error: unable to parse file \"sonSOA.xml\"\n");
    return(0);
  }
  /* Allocate memory for weather struct */
  int num = 6;
  while (num > 0) {
    wsrc[(num - 1)] = g_new0(weatherSource, 1);
    num--;
  }
  /* Fill rss entries from their respective fields */
  fill_entry_from_rss(wsrc[0], doc, 0);
  printf("%s\n", wsrc[0]->ili);
  xmlFreeDoc(doc);
  return 1;
}
int main() {
  fill_entry_from_rss_loop();
  return 0;
}

最佳答案

回答我自己的问题,这段代码中存在 2 个错误。首先,xml 节点在列出时以 1 而不是 0 开头。另外,xml 中的“ili”属性在我的代码中被错误地输入为“ili”,所以这也已修复。工作代码如下。

#include <glib-2.0/glib.h>

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

typedef struct weatherXmlSourceNode {
  char *bolge, *peryot, *ili, *durum;
  int mak;
} weatherSource;
weatherSource *wsrc[6];

xmlDocPtr doc;

char *grabNodeFromFile(xmlDocPtr xml_doc, char* nodeName, int item_index) {
  char xpath[64];
  xmlXPathContextPtr xpathCtx; 
  xmlXPathObjectPtr xpathObj; 
  xmlNodeSetPtr nodeset;

  sprintf(xpath, "/SOA/sehirler[%d]/%s",item_index,nodeName);

  xpathCtx = xmlXPathNewContext(xml_doc);

  if(xpathCtx == NULL) {
    fprintf(stderr,"Error: unable to create new XPath context\n");
    return(NULL);
  }

  /* Evaluate xpath expression */
  xpathObj = xmlXPathEvalExpression((xmlChar *)xpath, xpathCtx);
  xmlXPathFreeContext(xpathCtx);
  if(xpathObj == NULL) {
    fprintf(stderr,"Error: unable to evaluate xpath expression \"%s\"\n", xpath);
    return(NULL);
  }

  /* Check if xmlXPathEvalExpression had returned nonempty nodeset*/
  if (xmlXPathNodeSetIsEmpty(xpathObj->nodesetval)) {
    fprintf(stderr,"Error: empty set as a result of evaluation xpath expression \"%s\"",xpath);
    xmlXPathFreeObject (xpathObj);
    return(NULL);
  }

  nodeset = xpathObj->nodesetval;

  //there should be only one node in nodeset. So we return contents of the first node in nodeset
  return (char *)xmlNodeListGetString(xml_doc, nodeset->nodeTab[0]->xmlChildrenNode,1);
}

void fill_entry_from_rss(weatherSource *wsrc, xmlDocPtr filename, int doc_index) {
  /* Fill respective elements */
  wsrc->bolge = grabNodeFromFile(filename, "Bolge", doc_index);
  wsrc->peryot = grabNodeFromFile(filename, "Peryot", doc_index);
  wsrc->ili = grabNodeFromFile(filename, "ili", doc_index);
  wsrc->durum = grabNodeFromFile(filename, "Durum", doc_index);
  wsrc->mak = grabNodeFromFile(filename, "Mak", doc_index);
}

int fill_entry_from_rss_loop() {
  //int doc_item_index = 1;
  /* Load XML documents */
  doc = xmlParseFile("sonSOA.xml");
  if (doc == NULL) {
    fprintf(stderr, "Error: unable to parse file \"sonSOA.xml\"\n");
    return(0);
  }
  /* Allocate memory for weather struct */
  int num = 6;
  while (num > 0) {
    wsrc[(num - 1)] = g_new0(weatherSource, 1);
    num--;
  }
  /* Fill rss entries from their respective fields */
  fill_entry_from_rss(wsrc[0], doc, 1);
  printf("%s\n", wsrc[0]->ili);
  xmlFreeDoc(doc);
  return 1;
}
int main() {
  fill_entry_from_rss_loop();
  return 0;
}

关于c - libXML2 节点返回空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18482777/

相关文章:

c - 编辑我的代码以了解输入是否是二叉树

regex - 反向引用正则表达式在 sed 中不起作用

c - linux下如何用mingw使用splint

ruby - 如何解决 Windows 上 "libxml2 missing package"上的 "gem install ovirt-engine-sdk"错误?

ubuntu - 尝试在 ubuntu 上安装 libxml2-dev 时出现错误消息

c - 从 C 中的二进制文件中读取不同位数据的良好编码风格是什么?

c - 将 sqlite3_column_text() 返回到文字字符串

linux - 如何从 USB 加载 LUKS 密码,退回到键盘?

nginx - ./配置 : error: the HTTP XSLT module requires the libxml2/libxslt libraries

c - C 中的字符串文字以 %?