2017-03-16 12 views
1

xmlファイルの解析に深刻な問題があります。それをシンプルに保つために、のは、私がxmlsoft.orgで提供されるこのxmlファイル構造を、持っていると仮定してみましょう:libxml2を使用してXMLファイルを解析する方法を教えてください

XMLの似たファイルから各キーワードを取得するために
<?xml version="1.0"?> 
<story> 
    <storyinfo> 
    <author>John Fleck</author> 
    <datewritten>June 2, 2002</datewritten> 
    <keyword>example keyword</keyword> 
    </storyinfo> 
    <body> 
    <headline>This is the headline</headline> 
    <para>This is the body text.</para> 
    </body> 
</story> 

、開発者の目的は、このソリューション:

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <libxml/xmlmemory.h> 
#include <libxml/parser.h> 

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; 
} 

static 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; 
    } 

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

    cur = cur->next; 
    } 

    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); 
} 

私の疑いがある:例えば、<storyinfo>は私がから<id>(例えば)/ printf関数にアクセスできる方法

<storyinfo> 
... 
    <rev> 
     <id> 26546 </id> 
    </rev> 
</storyinfo> 

のように別の属性を持っていた場合など?要するに、もう一度、私が望むものを得るために、どうやってもっと深く深くすることができますか?

はxmlFreeDoc(DOC)行の前にparseDoc機能でこれを追加し

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

    cur = cur->next; 
    } 

新しい関数を作成し、parseRev(xmlDocPtrドキュメント、xmlNodePtrのCUR):上記の例では、私は成功せず、試してみました:

void 
parseRev (xmlDocPtr doc, xmlNodePtr cur) { 

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

どのようにすればいいですか?

+0

'storyinfo'ノードで' parseStory'から 'parseRev'を呼び出すだけです。 – nwellnhof

答えて

0

欠けているように見える重要な情報:次のcur-> nextを実行すると、すべての子を反復するときに、IMMEDIATEの子のみが使用されます。子供たちに反復するstorystoryinfostorybodyを与えます。

storyinfo内部rev命ので、あなたは、parseDocでそれを行うにはしたくない(DOC)ラインxmlFreeDoc前parseDoc関数に

これを追加します。 storyinfoの子を反復処理しているときにこのチェックを追加してください。

関連する問題