2013年7月8日月曜日

[libxml2] XPath によるxmlのパース

APIの多さと初心者向けの情報の少なさで苦戦してますが、ようやく超最低限なパースができたのでメモ


パースするXMLファイル
<?xml version="1.0" encoding="us-ascii" ?>
<orchestra>
  <players num="3">
    <player>aoki</player>
    <player>nakashima</player>
    <player>suzuki</player>
  </players>
</orchestra>

コード
#include <stdio.h>
#include <libxml/xmlreader.h>
#include <libxml/xpath.h>

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

  char *xml;
  char *xmlPath;
  int i;

  xmlXPathContextPtr cntxt;
  xmlXPathObjectPtr xmlObj;
  xmlDocPtr doc;
  xmlNodeSetPtr nodes;
  xmlNodePtr node;
  struct _xmlAttr *curAttr;

  xml = argv[1];
  xmlPath = argv[2];
  
  doc = xmlParseFile(xml);
  if(!doc) return -1;
  cntxt = xmlXPathNewContext(doc);
  if(!cntxt) return -1;
  xmlObj = xmlXPathEvalExpression((xmlChar *) xmlPath, cntxt);
  if(!xmlObj) return -1;

  nodes = xmlObj->nodesetval;

  // iterate node
  for(i=0;i<nodes->nodeNr; i++){
    node = xmlXPathNodeSetItem(nodes, i);

    // node name
    printf("=%s=\n", node->name);
    // properties
    curAttr = node->properties;
    while( curAttr != NULL ){
      printf("%s: %s\n", curAttr->name, curAttr->children->content);
      curAttr = curAttr->next;
    }
    if(node->children->content != NULL ){
      printf("content= %s\n",  node->children->content);
    }
  }


  xmlXPathFreeContext(cntxt);
  xmlFreeDoc(doc);
  xmlCleanupParser();

  return 0;
}

実行
./a.out sample/01.xml "//*"

出力
=orchestra=
content= 
  
=players=
num: 3
content= 
    
=player=
content= aoki
=player=
content= nakashima
=player=
content= suzuki


上記サンプルには、値を含んでいないcontentのケアを含んでいない。

参考サイト: http://d.hatena.ne.jp/hakutoitoi/20090319/1237397160 取っ掛かりのコード

0 件のコメント:

コメントを投稿