• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆 - 60, 文章 - 0, 評(píng)論 - 197, 引用 - 0
            數(shù)據(jù)加載中……

            用libxml 解析XML (一)

            Libxml 是一個(gè)實(shí)現(xiàn)讀、創(chuàng)建及操縱XML數(shù)據(jù)功能的C語言庫(kù)。這個(gè)指南提供例子代碼并給出它基本功能的解釋。在這個(gè)項(xiàng)目的主頁(yè)上有Libxml及更多關(guān)于它可用的資料。包含有完整的API文檔。這個(gè)指南并不能替代這些完整的文檔,但是闡明功能需要使用庫(kù)來完成基本操作。


            本指南中的例子代碼示范如何做到:
            解析文檔
            取得指定元素的文本
            添加一個(gè)元素及它的內(nèi)容
            添加一個(gè)屬性
            取得一個(gè)屬性的值
            例子的完整代碼包含在附錄中
             
            數(shù)據(jù)類型
            Libxml
            定義了許多數(shù)據(jù)類型,我們將反復(fù)碰到它們,它隱藏了雜亂的來源以致你不必處理它除非你有特定的需要。xmlChar  替代char,使用UTF-8編碼的一字節(jié)字符串。如果你的數(shù)據(jù)使用其它編碼,它必須被轉(zhuǎn)換到UTF-8才能使用libxml的函數(shù)。在libxml編碼支持WEB頁(yè)面有更多關(guān)于編碼的有用信息。
            XmlDoc
            包含由解析文檔建立的樹結(jié)構(gòu),xmlDocPtr是指向這個(gè)結(jié)構(gòu)的指針。
            xmlNodePtr and xmlNode
            包含單一結(jié)點(diǎn)的結(jié)構(gòu)xmlNodePtr是指向這個(gè)結(jié)構(gòu)的指針,它被用于遍歷文檔樹。
             
            解析文檔
            解析文檔時(shí)僅僅需要文件名并只調(diào)用一個(gè)函數(shù),并有錯(cuò)誤檢查。完整代碼:附錄C, Keyword例程代碼
             
            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;
            }
            定義解析文檔指針。
            定義結(jié)點(diǎn)指針(你需要它為了在各個(gè)結(jié)點(diǎn)間移動(dòng))。
            檢查解析文檔是否成功,如果不成功,libxml將指一個(gè)注冊(cè)的錯(cuò)誤并停止。
             
            注釋
            一個(gè)常見錯(cuò)誤是不適當(dāng)?shù)木幋a。XML標(biāo)準(zhǔn)文檔除了用UTF-8UTF-16外還可用其它編碼保存。如果文檔是這樣,libxml將自動(dòng)地為你轉(zhuǎn)換到UTF-8。更多關(guān)于XML編碼信息包含在XML標(biāo)準(zhǔn)中。
            取得文檔根元素
            檢查確認(rèn)當(dāng)前文檔中包含內(nèi)容。
            在這個(gè)例子中,我們需要確認(rèn)文檔是正確的類型。“Story”是在這個(gè)指南中使用文檔的根類型。
             
            取得元素內(nèi)容
             
            你找到在文檔樹中你要查找的元素后可以取得它的內(nèi)容。在這個(gè)例子中我們查找“story”元素。進(jìn)程將在冗長(zhǎng)的樹中查找我們感興趣的元素。我們假定期你已經(jīng)有了一個(gè)名為docxmlDocPtr和一個(gè)名為curxmlNodPtr
            cur = cur->xmlChildrenNode;
            while (cur != NULL) {  
                if ((!xmlStrcmp(cur->name, (const xmlChar *)"storyinfo"))){
                    parseStory (doc, cur);
                }
                cur = cur->next;
            }
             
            取得cur的第一個(gè)子結(jié)點(diǎn),cur指向文檔的根,即“story”元素。
            這個(gè)循環(huán)迭代通過“story”的子元素查找“storyinfo”。這是一個(gè)包含有我們將查找的“keywords”的元素。它使用了libxml字符串比較函數(shù)xmlStrcmp。如果相符,它調(diào)用函數(shù)parseStory
             
            void parseStory (xmlDocPtr doc, xmlNodePtr cur) {
            xmlChar *key;
            cur = cur->xmlChildrenNode;
            while (cur != NULL) {
                    if ((!xmlStrcmp(cur->name, (const xmlChar *)"keyword"))) {
                    key = xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
                          printf("keyword: %s\n", key);
                          xmlFree(key);
                    }
                    cur = cur->next;
                }
                return;
            }
            再次取得第一個(gè)子結(jié)點(diǎn)。
            像上面那個(gè)循環(huán)一樣,我們能過迭代,查找我們感興趣的叫做“keyword”的元素。
            當(dāng)我們找到元素“keyword時(shí),我們需要打印它包含在XML中的記錄的內(nèi)容,文本被包含于元素的子結(jié)點(diǎn)中,因此我們借助了cur-> xmlChildrenNode,為了取得文本,我們使用函數(shù)xmlNodeListGetString,它有一個(gè)文檔指針參數(shù),在這個(gè)例子中,我們僅僅打印它。
            注釋
            因?yàn)?/span>xmlNodeListGetString為它返回的字符串分配內(nèi)存,你必須使用xmlFree釋放它。
             
            使用XPath取得元素內(nèi)容
            除了一步步遍歷文檔樹查找元素外,Libxml2包含支持使用Xpath表達(dá)式取得指定結(jié)點(diǎn)集。完整的Xpath API文檔在這里。Xpath允許通過路徑文檔搜索匹配指定條件的結(jié)點(diǎn)。在下面的例子中,我們搜索文檔中所有的“keyword”元素。 
             
            注釋
            下面是Xpath完整的討論。它詳細(xì)的使用資料,請(qǐng)查閱Xpath規(guī)范。
            這個(gè)例子完整的代碼參見附錄D,XPath例程代碼。
            Using XPath requires setting up an xmlXPathContext and then supplying the XPath expression and the context to the xmlXPathEvalExpression

            function.
            The function returns an xmlXPathObjectPtr, which includes the set of nodes satisfying the XPath expression.
            使用XPath需要安裝xmlXPathContext才支持XPath表達(dá)式及xmlXPathEvalExpression函數(shù),這個(gè)函數(shù)返回一個(gè)xmlXPathObjectPtr,它包含有

            XPath表達(dá)式的結(jié)點(diǎn)集。
             
            xmlXPathObjectPtr
            getnodeset (xmlDocPtr doc, xmlChar *xpath){
            xmlXPathContextPtr context;
               xmlXPathObjectPtr result;
            context = xmlXPathNewContext(doc);
            result = xmlXPathEvalExpression(xpath, context);
            if(xmlXPathNodeSetIsEmpty(result->nodesetval)){
                   printf("No result\n");
                   return NULL;
               }
               xmlXPathFreeContext(context);
               return result;
            }
            首先定義變量
            初始化變量context
            應(yīng)用XPath表達(dá)式
            檢查結(jié)果
            由函數(shù)返回的xmlPathObjectPtr包含一個(gè)結(jié)點(diǎn)集和其它需要被迭代及操作的信息。在這個(gè)例子中我們的函數(shù)返回 xmlXPathObjectPtr,我們使用它打印我們文檔中keyword結(jié)點(diǎn)的內(nèi)容。這個(gè)結(jié)點(diǎn)集對(duì)象包含在集合(nodeNr)中的元素?cái)?shù)目及一個(gè)結(jié)點(diǎn)(nodeTab)數(shù)組。
             
            for (i=0; i < nodeset->nodeNr; i++) {
            keyword = xmlNodeListGetString(doc,
               nodeset->nodeTab[i]->xmlChildrenNode, printf("keyword: %s\n", keyword);
               xmlFree(keyword);
            }
            變量nodeset->Nr持有結(jié)點(diǎn)集中元素的數(shù)量。我們使用它遍歷數(shù)組。
            打印每個(gè)結(jié)點(diǎn)包含的內(nèi)容。
            注釋
            Note that we are printing the child node of the node that is returned, because the contents of the keyword element are a child text node.
            注意我們打印的是結(jié)點(diǎn)的子結(jié)點(diǎn)的返回值,因?yàn)?/span>keyword元素的內(nèi)容是一個(gè)子文本結(jié)點(diǎn)。


            寫元素
            寫元素內(nèi)容使用上面許多一樣的步驟解析文檔并遍歷樹。我們先解析文檔然后遍歷樹查找我們想插入元素的位置。在這個(gè)例子中,我們?cè)僖淮尾檎?/span>“storyinfo

            元素并插入一個(gè)keyword。然后我們裝文件寫入磁盤。完整代碼:附錄E,添加keyword例程
            本例中主要的不同在于parseStory
            void
            parseStory (xmlDocPtr doc, xmlNodePtr cur, char *keyword) {
            xmlNewTextChild (cur, NULL, "keyword", keyword);
               return;
            }
            XmlNewTextChild函數(shù)添加一個(gè)當(dāng)前結(jié)點(diǎn)的新的子元素到樹中
            一旦結(jié)點(diǎn)被添加,我們應(yīng)當(dāng)寫文檔到文件中。你是否想給元素指定一個(gè)命名空間?你能添加它,在我們的例子中,命名空間是NULL。
             
            xmlSaveFormatFile (docname, doc, 1);
             
            第一個(gè)參數(shù)是寫入文件的名,你注意到和我們剛剛讀入的文件名是一樣的。在這個(gè)例子中,我們僅僅覆蓋原來的文件。第二個(gè)參數(shù)是一個(gè)xmlDoc結(jié)構(gòu)指針,第三個(gè)參數(shù)設(shè)定為1,保證在輸出上寫入。

            posted on 2007-08-27 17:32 Normandy 閱讀(3651) 評(píng)論(3)  編輯 收藏 引用 所屬分類: XML

            評(píng)論

            # re: 用libxml 解析XML (一)  回復(fù)  更多評(píng)論   

            <?xml version="1.0" standalone="yes" ?>
            <!--
            Tests support of XML, XMLNS, and UTF-8. To pass, the user agent must load pass.html.
            -->
            <!DOCTYPE widget [
            <!ENTITY widgets-ns "http://www.w3.org/ns/widgets">
            <!ENTITY pass "pass&amp;.html">
            ]>
            <xyz:widget xmlnsyz="&widgets-ns;">
            <xyz:content src="&pass;"/>
            <xyz:name>bv</xyz:name>
            </xyz:widget>

            我第一次接觸libxml2, 調(diào)試了很長(zhǎng)時(shí)間也沒有頭緒,請(qǐng)幫忙看看,謝謝了。

            代碼是這樣的,
            xmlDoc *xmldoc = xmlParseFile(filename);
            會(huì)crash,
            2010-08-05 15:35 | talking1239

            # re: 用libxml 解析XML (一)  回復(fù)  更多評(píng)論   

            可否幫忙看下這個(gè)問題, 解析下面的xml,會(huì)crash。
            <?xml version="1.0" standalone="yes" ?>
            <!--
            Tests support of XML, XMLNS, and UTF-8. To pass, the user agent must load pass.html.
            -->
            <!DOCTYPE widget [
            <!ENTITY widgets-ns "http://www.w3.org/ns/widgets">
            <!ENTITY pass "pass&amp;.html">
            ]>
            <xyz:widget xmlnsyz="&widgets-ns;">
            <xyz:content src="&pass;"/>
            <xyz:name>bv</xyz:name>
            </xyz:widget>

            我第一次接觸libxml2, 調(diào)試很長(zhǎng)時(shí)間也沒有頭緒,請(qǐng)幫忙看看,謝謝了。

            xmlDoc *xmldoc = xmlParseFile(filename);
            會(huì)crash,
            2010-08-05 15:36 | talking1239
            久久久精品一区二区三区| 韩国免费A级毛片久久| 丰满少妇人妻久久久久久| 日韩精品无码久久一区二区三| 久久婷婷综合中文字幕| 97久久精品午夜一区二区| 无码人妻精品一区二区三区久久| 四虎国产精品成人免费久久| 区亚洲欧美一级久久精品亚洲精品成人网久久久久 | 狠狠色丁香久久婷婷综合图片| 品成人欧美大片久久国产欧美| 久久国产精品一区二区| AV无码久久久久不卡网站下载| 国产精品18久久久久久vr| 国产精品久久久久久久久鸭 | 久久久久亚洲精品天堂久久久久久 | 99精品伊人久久久大香线蕉| 青青草原综合久久大伊人精品| 国产一区二区精品久久| 精品人妻久久久久久888| www.久久热| 国产精品成人99久久久久91gav| 国产精品欧美亚洲韩国日本久久| 久久国产视屏| 狠狠综合久久综合88亚洲| 浪潮AV色综合久久天堂| 99久久www免费人成精品| 亚洲а∨天堂久久精品| 久久国产精品无码HDAV| 99久久精品免费看国产一区二区三区 | 久久亚洲精品中文字幕| 亚洲综合久久综合激情久久| 少妇被又大又粗又爽毛片久久黑人| 国产成人精品久久| 一级做a爰片久久毛片人呢| 亚洲精品tv久久久久| 久久综合给合久久狠狠狠97色| 久久精品国产WWW456C0M| 一本色综合网久久| 久久中文字幕无码专区| 99国产欧美精品久久久蜜芽|