日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

XML常见的操作

發布時間:2023/12/13 asp.net 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 XML常见的操作 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. ? 創建XML文檔

(1)創建一個XML文檔非常簡單,其流程如下:

①??? 用xmlNewDoc函數創建一個文檔指針doc。

②??? 用xmlNewNode函數創建一個節點指針root_node。

③??? 用xmlDocSetRootElement將root_node設置為doc的根結點。

④??? 給root_node添加一系列的子節點,并設置子節點的內容和屬性。

⑤??? 用xmlSaveFile將XML文檔存入文件。

⑥??? 用xmlFreeDoc關閉文檔指針,并清除本文檔中所有節點動態申請的內存。

有多種方式可以添加子節點,如可以用xmlNewTextChild直接添加一個文本子節點。也可以先創建新節點,然后用xmlAddChild將新節點加入到上層節點中。

?

(2)創建xml文件舉例

CreateXmlFile.c源代碼如下:

#include <stdio.h>

#include <libxml/parser.h>

#include <libxml/tree.h>

int main()

{

? //定義文檔和節點指針

? xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");

???? xmlNodePtr root_node = xmlNewNode(NULL,BAD_CAST "root");

???? //設置根節點

???? xmlDocSetRootElement(doc,root_node);

???? //在根節點中直接創建節點

???? xmlNewTextChild(root_node, NULL, BAD_CAST "newNode1", BAD_CAST "newNode1 content");

???? xmlNewTextChild(root_node, NULL, BAD_CAST "newNode2", BAD_CAST "newNode2 content");

???? xmlNewTextChild(root_node, NULL, BAD_CAST "newNode3", BAD_CAST "newNode3 content");

???? //創建一個節點,設置其內容和屬性,然后加入根結點

???? xmlNodePtr node = xmlNewNode(NULL,BAD_CAST "node2");

???? xmlNodePtr content = xmlNewText(BAD_CAST "NODE CONTENT");

???? xmlAddChild(root_node,node);

???? xmlAddChild(node,content);

???? xmlNewProp(node,BAD_CAST "attribute",BAD_CAST "yes");

???? //創建一個兒子和孫子節點

???? node = xmlNewNode(NULL, BAD_CAST "son");

???? xmlAddChild(root_node,node);

???? xmlNodePtr grandson = xmlNewNode(NULL, BAD_CAST "grandson");

???? xmlAddChild(node,grandson);

???? xmlAddChild(grandson, xmlNewText(BAD_CAST "This is a grandson node"));

???? //存儲xml文檔

???? int nRel = xmlSaveFile("CreateXml.xml",doc);

???? if (nRel != -1)

???? {

??????? printf("一個xml文檔被創建,寫入%d個字節\n", nRel);

???? }

???? //釋放文檔內節點動態申請的內存

???? xmlFreeDoc(doc);

???? return 1;

}

編譯 gcc CreateXmlFile.c -o CreateXmlFile -I/usr/local/include/libxml2?????? -lxml2。

執行./CreateXmlFile,會生成一個XML文件CreatedXml.xml。打開后如下所示:

<?xml version="1.0"?>

<root>

??? <newNode1>newNode1 content</newNode1>

??? <newNode2>newNode2 content</newNode2>

??? <newNode3>newNode3 content</newNode3>

??? <node2 attribute="yes">NODE CONTENT</node2>

??? <son>

?????? <grandson>This is a grandson node</grandson>

??? </son>

</root>

最好使用類似XMLSPY這樣的工具打開,因為這些工具可以自動整理XML文件的柵格,否則很有可能是沒有任何換行的一個XML文件,可讀性較差。

2. ? 解析XML文檔

(1)XML解析流程

解析一個XML文檔,從中取出想要的信息,例如節點中包含的文字,或者某個節點的屬性。其流程如下:

①??? 用xmlReadFile函數讀入一個文件,并返回一個文檔指針doc。

②??? 用xmlDocGetRootElement函數得到根節點curNode。

③??? 此時curNode->xmlChildrenNode就是根節點的首個兒子節點,該兒子節點的兄弟節點可用next指針進行輪詢。

④??? 輪詢所有子節點,找到所需的節點,用xmlNodeGetContent取出其內容。

⑤??? 用xmlHasProp查找含有某個屬性的節點,屬性列表指針xmlAttrPtr將指向該節點的屬性列表。

⑥??? 取出該節點的屬性,用xmlGetProp取出其屬性值。

⑦??? xmlFreeDoc函數關閉文檔指針,并清除本文檔中所有節點動態申請的內存。

?

(2)XML解析舉例

ParseXmlFile.c源代碼如下:

#include <stdio.h>

#include <libxml/parser.h>

#include <libxml/tree.h>

int main(int argc, char* argv[])

{

??? xmlDocPtr doc;?????????? //定義解析文件指針

??? xmlNodePtr curNode;????? //定義結點指針

??? xmlChar *szKey;????????? //臨時字符串變量

??? char *szDocName;

??? if (argc <= 1)

??? {

??????? printf("Usage: %s docname", argv[0]);

??????? return(0);

??? }

??? szDocName = argv[1];

??? doc = xmlReadFile(szDocName,"GB2312",XML_PARSE_RECOVER);

??? //解析文件

??? //檢查解析文檔是否成功,如果不成功,libxml將報錯并停止解析。

??? //一個常見錯誤是不適當的編碼,XML標準文檔除了用UTF-8或UTF-16外還可用其它編碼保存

??? if (NULL == doc)

??? {?

??????? fprintf(stderr,"Document not parsed successfully.");????

??????? return -1;

??? }

??? //獲取根節點

??? curNode = xmlDocGetRootElement(doc);

??? if (NULL == curNode)

??? {

??????? fprintf(stderr,"empty document");

??????? xmlFreeDoc(doc);

??????? return -1;

??? }

??? //確認根元素名字是否符合

??? if (xmlStrcmp(curNode->name, BAD_CAST "root"))

??? {

??????? fprintf(stderr,"document of the wrong type, root node != root");

??????? xmlFreeDoc(doc);

??????? return -1;

??? }

??? curNode = curNode->xmlChildrenNode;

??? xmlNodePtr propNodePtr = curNode;

??? while(curNode != NULL)

??? {

??????? //取出節點中的內容

??????? if ((!xmlStrcmp(curNode->name, (const xmlChar *) "newNode1")))

??????? {

??????????? szKey = xmlNodeGetContent(curNode);

??????? ????printf("newNode1: %s\n", szKey);

??????????? xmlFree(szKey);

??????? }

??????? //查找帶有屬性attribute的節點

??????? if (xmlHasProp(curNode,BAD_CAST "attribute"))

??????? {

??????????? propNodePtr = curNode;

??????? }

??????? curNode = curNode->next;

??? }

??? //查找屬性

??? xmlAttrPtr attrPtr = propNodePtr->properties;

??? while (attrPtr != NULL)

??? {

??????? if (!xmlStrcmp(attrPtr->name, BAD_CAST "attribute"))

??????? {

??????????? xmlChar* szAttr = xmlGetProp(propNodePtr,BAD_CAST "attribute");

??????????? printf("get attribute=%s\n", szAttr) ;

??????????? xmlFree(szAttr);

??????? }

??????? attrPtr = attrPtr->next;

??? }

??? xmlFreeDoc(doc);

??? return 0;

}

編譯 gcc ParseXmlFile.c -o ParseXmlFile -I/usr/local/include/libxml2? -lxml2。

執行 ./ParseXmlFile CreateXml.xml,執行結果如下:

newNode1: newNode1 content

get attribute=yes

3. ? 修改XML文檔

有了上面的基礎,修改XML文檔的內容就簡單了。首先打開一個已經存在的XML文檔,順著根結點找到需要添加、刪除、修改的地方,調用相應的XML函數對節點進行增、刪、改操作。

需要注意的是,并沒有xmlDelNode或者xmlRemoveNode函數,刪除節點需使用以下一段代碼:

?????? if (!xmlStrcmp(curNode->name, BAD_CAST "newNode1"))

?????? {

?????????? xmlNodePtr tempNode;

?????????? tempNode = curNode->next;

?????????? xmlUnlinkNode(curNode);

?????????? xmlFreeNode(curNode);

?????????? curNode = tempNode;

?????????? continue;

?????? }

此段代碼完成將當前節點從文檔中斷鏈(unlink),這樣此XML文檔就不會再包含這個節點,該節點斷鏈后需使用xmlFreeNode來釋放該節點申請的動態內存空間。

4. ? 使用XPath查找XML文檔

在libxml2中使用XPath非常簡單,其流程如下:

①??? 定義一個XPath上下文指針xmlXPathContextPtr context,并且使用xmlXPathNewContext函數來初始化這個指針。

②??? 定義一個XPath對象指針xmlXPathObjectPtr result,并且使用xmlXPathEvalExpression函數來計算XPath表達式,得到查詢結果,將結果存入對象指針中。

③??? 使用result->nodesetval得到節點集合指針,其中包含了所有符合XPath查詢結果的節點。

④??? 使用xmlXPathFreeContext釋放上下文指針。

⑤??? 使用xmlXPathFreeObject釋放XPath對象指針。

?

XPath操作代碼示例如下:

xmlXPathObjectPtr getNodeSet(xmlDocPtr doc, const xmlChar *szXpath)

{

??? xmlXPathContextPtr context;??? //XPath上下文指針

??? xmlXPathObjectPtr result;?????? //XPath對象指針,用來存儲查詢結果

??? context = xmlXPathNewContext(doc);???? //創建一個XPath上下文指針

??? if (context == NULL)

??? {??

?????? printf("context is NULL"n");

?????? return NULL;

??? }

??? result = xmlXPathEvalExpression(szXpath, context); //查詢XPath表達式,得到一個查詢結果

??? xmlXPathFreeContext(context);???????????? //釋放上下文指針

??? if (result == NULL)

??? {

?????? printf("xmlXPathEvalExpression return NULL"n");

?????? return NULL;

??? }

??? if (xmlXPathNodeSetIsEmpty(result->nodesetval))?? //檢查查詢結果是否為空

??? {

?????? xmlXPathFreeObject(result);

?????? printf("nodeset is empty"n");

?????? return NULL;

??? }

??? return result;???

}

5. ? 用iconv解決XML中字符集問題

libxml2中默認的內碼是UTF-8,所有使用libxml2進行處理的xml文件,必須首先顯式或者默認轉換為UTF-8編碼才能被處理。

要在XML中使用中文,就必須能夠在UTF-8和GB2312之間進行轉換。libxml2提供了默認的內碼轉換機制,并且在libxml2的Tutorial中有一個例子,事實證明這個例子并不很適合用來轉換中文。

有些場合需要使用iconv來進行編碼轉換,libxml2本身也是使用iconv進行編碼轉換的。iconv是一個專門用來進行編碼轉換的庫,基本上支持目前所有常用的編碼,它是glibc庫的一個部分。

本節其實和libxml沒有太大關系,可以把它簡單看作是一個編碼轉換方面的專題。下文提供了一個通用轉碼函數,并在此基礎上實現了兩個轉碼封裝函數,即從UTF-8轉換到GB2312的函數u2g,以及反向轉換的函數g2u。其代碼如下:

#include <iconv.h>

#include <string.h>

//代碼轉換,從一種編碼轉為另一種編碼??

int code_convert(char* from_charset, char* to_charset, char* inbuf,

?????????????? int inlen, char* outbuf, int outlen)

{

??? iconv_t cd;

??? char** pin = &inbuf;? ?

??? char** pout = &outbuf;

??? cd = iconv_open(to_charset,from_charset);??

??? if(cd == 0)

?????? return -1;

??? memset(outbuf,0,outlen);??

??? if(iconv(cd,(const char**)pin,(unsigned int *)&inlen,pout,(unsigned int*)&outlen)

?????? == -1)

?????? return -1;??

??? iconv_close(cd);

??? return 0;??

}

//UNICODE碼轉為GB2312碼??

//成功則返回一個動態分配的char*變量,需要在使用完畢后手動free,失敗返回NULL

char* u2g(char *inbuf)??

{

??? int nOutLen = 2 * strlen(inbuf) - 1;

??? char* szOut = (char*)malloc(nOutLen);

??? if (-1 == code_convert("utf-8","gb2312",inbuf,strlen(inbuf),szOut,nOutLen))

??? {

?????? free(szOut);

?????? szOut = NULL;

??? }

??? return szOut;

}??

//GB2312碼轉為UNICODE碼??

//成功則返回一個動態分配的char*變量,需要在使用完畢后手動free,失敗返回NULL

char* g2u(char *inbuf)??

{

??? int nOutLen = 2 * strlen(inbuf) - 1;

??? char* szOut = (char*)malloc(nOutLen);

??? if (-1 == code_convert("gb2312","utf-8",inbuf,strlen(inbuf),szOut,nOutLen))

??? {

?????? free(szOut);

?????? szOut = NULL;

??? }

??? return szOut;

}

下面以UTF-8到GB2312轉碼流程說明上文中轉碼函數的使用,使用流程如下:

①??? 得到一個UTF-8的字符串szSrc。

②??? 定義一個char *的字符指針szDes,并不需要給它動態申請內存。

③??? 調用szDes = u2g(szSrc),這樣szDes就指向轉換后GB2312編碼的字符串。

④??? 使用完這個字符串后使用free(szDes)來釋放內存。

如果轉碼文件可以選擇系統調用來進行文件轉碼。下文中f表示from,t表示to,其轉碼方法如下:

system("iconv –f 源格式 –t 目標格式 源文件 >目標文件")

system("iconv –f? GB18030 –t UTF-8? test_gb.txt > test_utf.txt")

總結

以上是生活随笔為你收集整理的XML常见的操作的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。