libxml学习手册

参考文献:Libxml Tutorial


数据类型:

Libxml声明了很多数据类型:

xmlChar:是对char类型的替代,其为一个字节的UTF-8编码字符。如果你的数据使用其他的编码,必须转换为UTF-8才能提供给libxml的函数使用。

xmlDoc:包含由解析的doc创建的树的结构体。xmlDocPtr是指向该结构的指针。

xmlNodePtr 和 xmlNode:包含单个结点的结构。xmlNodePtr是指向该结构的指针,用来遍历文档树。


解析文件:

只需要文件名和单一的函数调用就可以解析文件并实现错误检测。完整代码参见:Code for Keyword Example


xmlDocPtr doc;
xmlNodePtr cur;

doc = xmlParseFile(docname);

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

cur = xmlDocGetRootElement(doc);

if(cur == NULL){
    fprintf(stderr, "empty document\n");
    xmlFreeDoc(doc);
    return;
}

if(xmlStrcmp(cur->name, (const xmlChar *) "story")){
    fprintf(stderr, "document of the wrong type, root node != story");
    xmlFreeDoc(doc);
    return;
}


查询元素内容:

        查询元素的内容涉及到遍历文档树知道找到需要的内容。在这个例子中,我们将需找在"story"元素中名称为"keyword"的元素。假设已经有称为doc的xmlDocPtr,和称为cur的xmlNodePtr。


cur = cur->xmlChildrenNode;
while(cur != NULL){
    if((!xmlStrcmp(cur->name, (const xmlChar *)"storyinfo"))){
         parseStory(doc, cur);
    }
cur = cur->next;
}

首先,得到第一个孩子结点cur。这是,cur指元素“story”,该元素为文档的根。

然后,循环迭代story的孩子元素,寻找名为storyinfo的元素。这个元素是包含“keyword"的元素。这里使用libxml的字符串比较函数xmlStrcmp。如果找到匹配项,调用函数parseStory。

xmlChar *key;
cur = cur->xmlChildrenNode;
while (cur!=NULL){
    if((!xmlStrcmp(cur->name, (const xmlChar *)"keyboard"))){
        key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
        printf("keyword: %s\n", key);
        xmlFree(key);
    }
cur = cur->mext;
}

首先得到第一个孩子结点。

迭代所有结点,寻找匹配元素,在本例中是"keyword"

找到keyword元素后,打印出他的内容。谨记,在XML中,元素中包含的文本是该元素的孩子结点,所有我们使用cur->xmlChildrenNode.为了查询它,我们使用函数xmlNodeListGetString,该函数把doc作为一个参数。

  提示:由于xmlNodeListGetString为返回的字符串分配内存,所有必须使用xmlFree释放它。


使用XPath来查询元素内容:

除了遍历文档树来寻找元素外,Libxml2包含XPath表达式支持来查询匹配指定匹配的一些列结点。

XPath允许查询整个文档来寻找指定文本的匹配。在下面的例子中,我们查询整个文档来寻找keyword元素的内容。

使用XPath需要建立一个xmlXPathContext然后提供XPath表达式和内容给xmlXPathEvalExpression函数。这个函数返回一个XPathObjectPtr,其中包含满足XPath表达式的结点集合。


xmlXPathObjectPtr
getnodeset (xmlDocPtr doc, xmlChar *xpath){
  xmlXPathContextPtr context;
  xmlXPathObjectPtr result;
  context = xmlXPathNewContext(doc);
  result = xmlXPathEvalExpression(xpath, context);
   if(xmlXPathNdeSetIsEmpty(result->nodesetval)){
    xmlXPathFreeObject(result);
    printf("No result\n");
    return NULL;
首先定义变量context;

然后初始化context变量;

使用XPath表达式;

检查result并且释放内存。


函数返回的xmlPathObjectPtr包含结点集合和用来迭代结合的其他的信息。对于本例,返回xmlXPathObjectPtr。我们使用它来打印keyword结点的内容。结点集合对象包括该集合中元素数目(nodeNr)和结点数组(nodeTab);

for(i = 0; i < nodeset->nodeNr; i++){
  keyword = xmlNodeListGetString(doc, nodeset->nodeTab[i]->xmlChildrenNode, 1);
  printf("keyword: %s\n", keyword);
  xmlFree(keyword);
}

写元素内容:


写元素内容采用和上面类似的步骤:解析文档、遍历树。解析文档,遍历树找到我们要插入文档的点。在下面的例子中,我们寻找”storyinfo“元素,并且插入一个keyword。然后将文件写入到磁盘。

void parseStory(xmlDocPtr doc, xmlNodePtr cur, char *keyword){
   xmlNewTextChild(cur, NULL, "keyword", keyword);
   return;
}

xmlNewTextChild函数增加新的孩子元素。

添加完元素,我们希望将文档写入文件。你是否想添加命名空间,你可以在这里添加它。在我们的例子中,命名空间是NULL。

xmlSaveFormatFile(docname, doc, 1);

第一个参数是文件的名字。


写入属性:

写入属性类似于写入文本。在下面例子中,我们添加一个引用URI 到我们的文档。

一个引用是story元素的孩子,所以查找防止新元素和属性的地方很简单。

xmlAttrPtr newattr;

我们另外需要一个额外的xmlNodePtr:
xmlNodePtr newnode;

newnode = xmlNewTextChild(cur, NULL, "reference", NULL);
newattr = xmlNewProp(newnode, "uri",uri);

使用xmlNewTextChild函数我们添加一个新节点。


查询属性:

void getReference(xmlDocPtr doc, xmlNodePtr cur){
  xmlChar *uri;
  cur = cur->xmlChildrenNode;
  while(cur != NULL){
    if((!xmlStrcmp(cur->name, (const xmlChar *)"reference"))){
      uri = xmlGetProp(cur, "uri");
      printf("uri: %s\n", uri);
      xmlFree(uri);
    }
    cur = cur->next;
  }
  return;
}

编码转换:

libxml存储和操作的数据用UTF-8格式编码。使用其他编码格式的数据需要转换到UTF-8,然后传入libxml函数。如果你想要将程序输出为其他格式,而不是UTF-8,你必须转换它。

libxml使用iconv转换数据。如果没有iconv,只有UTF-8, UTF-16和ISO-8859-1可以作为外部格式使用。使用iconv,任何格式可以被转化为UTF-8,或从UTF-8转化为任何格式。目前iconv支持超过150种不同的字符格式。


本例创建一个简单的文档,然后添加内容,内容由命令行提供到文档根元素,然后使用适当的编码输出结构到stdout。在这个例子中,我们使用ISO-8859-1编码。

xmlCharEncodingHandlerPtr handler;
size = (int)strlen(in) + 1;
out_size = size * 2 - 1;
out = malloc((size_t)out_size);
handler = xmlFindCharEncodingHandler(encoding);
handler->input(out, &out, size, in, &temp);
xmlSaveFormatFileEnc("-", doc, encoding, 1)


简单的例子:

  1 <?xml version="1.0"?>
  2 <story>
  3   <storyinfo>
  4     <author>John Fleck</author>
  5     <datewritten>June 2, 2002</datewritten>
  6     <keyword>example keyword</keyword>
  7   </storyinfo>
  8   <body>
  9     <headline>This is the headline</headline>
 10     <para>This is the body text.</para>                                             
 11   </body>
 12 </story>

Code for Keyword Example:

  1 #include <stdio.h>                                                                                                         
  2 #include <string.h>
  3 #include <stdlib.h>
  4 #include <libxml/xmlmemory.h>
  5 #include <libxml/parser.h>
  6 
  7 void
  8 parseStory(xmlDocPtr doc, xmlNodePtr cur){
  9     xmlChar *key;
 10     cur = cur->xmlChildrenNode;
 11     while(cur != NULL){
 12         if((!xmlStrcmp(cur->name, (const xmlChar *)"keyword"))){
 13             key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
 14             printf("keyword: %s\n", key);
 15             xmlFree(key);
 16         }
 17         cur = cur->next;
 18     }
 19     return;
 20 }
 21 
 22 static void
 23 parseDoc(char *docname){
 24     xmlDocPtr doc;
 25     xmlNodePtr cur;
 26 
 27     doc = xmlParseFile(docname);
 28 
 29     if(doc == NULL){
 30         fprintf(stderr, "Document not parsed successfully.\n");
 31         return;
 32     }
 33 
 34     cur = xmlDocGetRootElement(doc);
 35 
 36     if(cur == NULL){
 37         fprintf(stderr, "empty document\n");
 38         xmlFreeDoc(doc);
 39         return;
 40     }
 41 
 42     if(xmlStrcmp(cur->name, (const xmlChar *)"story")){
 43         fprintf(stderr, "document of the wrong type, root node != story\n");
 44         xmlFreeDoc(doc);
 45         return;
 46     }
 47 
 48     cur = cur->xmlChildrenNode;
 49     while(cur != NULL){
 50         if((!xmlStrcmp(cur->name, (const xmlChar *)"storyinfo"))){
 51             parseStory(doc, cur);
 52         }
 53         cur = cur->next;
 54     }
 55     xmlFreeDoc(doc);
 56     return;
 57 }
 58 
 59 int 
 60 main(int argc, char **argv){
 61     char *docname;
 62     if(argc <= 1){
 63         printf("Usage: %s docname\n", argv[0]);
 64         return 0;
 65     }
 66     docname = argv[1];
 67     parseDoc(docname);
 68     return 1;
 69 } 

Code for XPath Example:

  1 #include <libxml/parser.h>                                                                                                 
  2 #include <libxml/xpath.h>
  3 
  4 xmlDocPtr
  5 getdoc(char *docname){
  6     xmlDocPtr doc;
  7     doc = xmlParseFile(docname);
  8     if(doc == NULL){
  9         fprintf(stderr, "Document not parsed successfully.\n");
 10         return NULL;
 11     }
 12     return doc;
 13 }
 14 
 15 xmlXPathObjectPtr
 16 getnodeset(xmlDocPtr doc, xmlChar *xpath){
 17     xmlXPathContextPtr context;
 18     xmlXpathObjectPtr result;
 19 
 20     context = xmlXPathNewContext(doc);
 21     if(context == NULL){
 22         printf("Error in xmlXPathNewContext\n");
 23         return NULL;
 24     }
 25     result = xmlXPathEvalExpression(xpath, context);
 26     xmlXPathFreeContext(context);
 27     if(result == NULL){
 28         printf("Error in xmlXPathEvalExpression\n");
 29         return NULL;
 30     }
 31     if(xmlXPathNodeSetIsEmpty(result->nodesetval)){
 32         xmlXPathFreeObject(result);
 33         printf("No result\n");
 34         return NULL;
 35     }
 36     return result;
 37 }
 38 int
 39 main(int argc, char **argv){
 40     char *docname;
 41     xmlDocPtr doc;
 42     xmlChar *xpath = (xmlChar *) "//keyword";
 43     xmlNodeSetPtr nodeset;
 44     xmlXPathObjectPtr result;
 45     int i;
 46     xmlChar *keyword;
 47     if(argc <= 1){
 48         printf("Usage: %s docname\n", argv[0]);
 49         return 0;
 50     }
 51     docname = argv[1];
 52     doc = getdoc(docname);
 53     result = getnodeset(doc, xpath);
 54     if(result){
 55         nodeset = result->nodesetval;
 56         for(i = 0; i < nodeset->nodeNr; i++){
 57             keyword = xmlNodeListGetString(doc, nodeset->nodeTab[i], 1);
 58             printf("keyword: %s\n", keyword);
 59             xmlFree(keyword);
 60         }
 61         xmlXPathFreeObject(result);
 62     }
 63     xmlFreeDoc(doc);
 64     xmlCleanupParser();
 65     return 1;
 66 }                                     

Code for Add Keyword Example:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
void
parseStory (xmlDocPtr doc, xmlNodePtr cur, char *keyword) {
  xmlNewTextChild (cur, NULL, "keyword", keyword);
  return;
}
xmlDocPtr
parseDoc(char *docname, char *keyword) {
  xmlDocPtr doc;
  xmlNodePtr cur;
  doc = xmlParseFile(docname);
  if (doc == NULL ) {
    fprintf(stderr,"Document not parsed successfully. \n");
    return (NULL);
  }
  cur = xmlDocGetRootElement(doc);
  if (cur == NULL) {
    fprintf(stderr,"empty document\n");
    xmlFreeDoc(doc);
    return (NULL);
  }
  if (xmlStrcmp(cur->name, (const xmlChar *) "story")) {
    fprintf(stderr,"document of the wrong type, root node != story");
    xmlFreeDoc(doc);
    return (NULL);
  }
  cur = cur->xmlChildrenNode;
  while (cur != NULL) {
    if ((!xmlStrcmp(cur->name, (const xmlChar *)"storyinfo"))){
    parseStory (doc, cur, keyword);
  }
  cur = cur->next;
}
return(doc);
}
int
main(int argc, char **argv) {
  char *docname;
  char *keyword;
  xmlDocPtr doc;
  if (argc <= 2) {
    printf("Usage: %s docname, keyword\n", argv[0]);
    return(0);
  }
  docname = argv[1];
  keyword = argv[2];
  doc = parseDoc (docname, keyword);
  if (doc != NULL) {
    xmlSaveFormatFile (docname, doc, 0);
    xmlFreeDoc(doc);
  }
  return (1);
}

Code for Add Attribute Example:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
xmlDocPtr
parseDoc(char *docname, char *uri) {
  xmlDocPtr doc;
  xmlNodePtr cur;
  xmlNodePtr newnode;
  xmlAttrPtr newattr;
  doc = xmlParseFile(docname);
  if (doc == NULL ) {
    fprintf(stderr,"Document not parsed successfully. \n");
    return (NULL);
  }
  cur = xmlDocGetRootElement(doc);
  if (cur == NULL) {
    fprintf(stderr,"empty document\n");
    xmlFreeDoc(doc);
    return (NULL);
  }
  if (xmlStrcmp(cur->name, (const xmlChar *) "story")) {
    fprintf(stderr,"document of the wrong type, root node != story");
    xmlFreeDoc(doc);
    return (NULL);
  }
  newnode = xmlNewTextChild (cur, NULL, "reference", NULL);
  newattr = xmlNewProp (newnode, "uri", uri);
  return(doc);
}
int
main(int argc, char **argv) {
  char *docname;
  char *uri;
  xmlDocPtr doc;
  if (argc <= 2) {
    printf("Usage: %s docname, uri\n", argv[0]);
    return(0);
  }
  docname = argv[1];
  uri = argv[2];
  doc = parseDoc (docname, uri);
  if (doc != NULL) {
    xmlSaveFormatFile (docname, doc, 1);
    xmlFreeDoc(doc);
  }
  return (1);
}

Code for Retrieving Attribute Value Example:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
void
getReference (xmlDocPtr doc, xmlNodePtr cur) {
  xmlChar *uri;
  cur = cur->xmlChildrenNode;
  while (cur != NULL) {
    if ((!xmlStrcmp(cur->name, (const xmlChar *)"reference"))) {
      uri = xmlGetProp(cur, "uri");
      printf("uri: %s\n", uri);
      xmlFree(uri);
    }
    cur = cur->next;
  }
  return;
}
void
parseDoc(char *docname) {
  xmlDocPtr doc;
  xmlNodePtr cur;
  doc = xmlParseFile(docname);
  if (doc == NULL ) {
    fprintf(stderr,"Document not parsed successfully. \n");
    return;
  }
  cur = xmlDocGetRootElement(doc);
  if (cur == NULL) {
    fprintf(stderr,"empty document\n");
    xmlFreeDoc(doc);
    return;
  }
  if (xmlStrcmp(cur->name, (const xmlChar *) "story")) {
    fprintf(stderr,"document of the wrong type, root node != story");
    xmlFreeDoc(doc);
    return;
  }
  getReference (doc, cur);
  xmlFreeDoc(doc);
  return;
}
int
main(int argc, char **argv) {
  char *docname;
  if (argc <= 1) {
    printf("Usage: %s docname\n", argv[0]);
    return(0);
  }
  docname = argv[1];
  parseDoc (docname);
  return (1);
}

Code for Encoding Conversion Example:

#include <string.h>
#include <libxml/parser.h>
unsigned char*
convert (unsigned char *in, char *encoding)
{
  unsigned char *out;
  int ret,size,out_size,temp;
  xmlCharEncodingHandlerPtr handler;
  size = (int)strlen(in)+1;
  out_size = size*2-1;
  out = malloc((size_t)out_size);
  if (out) {
    handler = xmlFindCharEncodingHandler(encoding);
    if (!handler) {
      free(out);
      out = NULL;
    }
  }
  if (out) {
    temp=size-1;
    ret = handler->input(out, &out_size, in, &temp);
    if (ret || temp-size+1) {
      if (ret) {
        printf("conversion wasn't successful.\n");
      } else {
        printf("conversion wasn't successful. converted: }
        free(out);
        out = NULL;
      } else {
        out = realloc(out,out_size+1);
        out[out_size]=0; /*null terminating out*/
      }
   } else {
     printf("no mem\n");
   }
   return (out);
}
int
main(int argc, char **argv) {
  unsigned char *content, *out;
  xmlDocPtr doc;
  xmlNodePtr rootnode;
  char *encoding = "ISO-8859-1";
  if (argc <= 1) {
    printf("Usage: %s content\n", argv[0]);
    return(0);
  }
  content = argv[1];
  out = convert(content, encoding);
  doc = xmlNewDoc ("1.0");
  rootnode = xmlNewDocNode(doc, NULL, (const xmlChar*)"root", out);
  xmlDocSetRootElement(doc, rootnode);
  xmlSaveFormatFileEnc("-", doc, encoding, 1);
  return (1);
}



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值