2012-03-21 2 views
2

나는 추적의 XML 파일을 구문 분석하려고 해요 :miniXML 파싱 C의 API

<root>Root 
    <pai>Pai_1 
     <filho>Pai1,Filho1</filho> 
     <filho>Pai1,Filho2</filho> 
    </pai> 
    <pai>Pai_2 
     <filho>Pai2,Filho1</filho> 
     <filho>Pai2,Filho2</filho> 
    </pai> 
</root> 

나는 추적의 C 코드를 사용하고 있습니다 :

//... open file 
xml_tree = mxmlLoadFile(NULL, fp, MXML_TEXT_CALLBACK); 

node = xml_tree; 
printf("%s\n", mxmlGetText(node, NULL)); 
// here the return is: Root 
// I expected: Root, OK 

node = xml_tree->child; 
printf("%s\n", mxmlGetText(node, NULL)); 
// here the return is: Root 
// I expected: Pai_1, not OK 

node = mxmlGetFirstChild(xml_tree); 
printf("%s\n", mxmlGetText(node, NULL)); 
// here the return is: Root 
// I expected: Pai_1, not OK 

node = mxmlFindElement(xml_tree, xml_tree, "pai", NULL, NULL, MXML_DESCEND); 
printf("%s\n", mxmlGetText(node, NULL)); 
// here the return is: Pai_1 
// I expected: Pai_1, OK 

node = mxmlGetNextSibling(node); 
printf("%s\n", mxmlGetText(node, NULL)); 
// here the return is: (NULL) 
// I expected: Pai_2, not OK 

가 어떻게 루트의 자식에 액세스 할 수 있습니까? 내 접근 개념이 잘못된 곳은 어디입니까?

감사합니다. @RutgersMike 응답 후


편집

나는 minixml의 개념을 이해하려고하기 위해 while 루프를 확장 :이이었다

root = mxmlLoadFile(NULL,fp,MXML_TEXT_CALLBACK); 
node = root; 

printf("------- Root\n"); 
fprintf(stdout,"Element = %s\n",mxmlGetElement(node)); 
fprintf(stdout," Value = %s\n",mxmlGetText(node,0)); 
printf("\n"); 

printf("------- First child of Root\n"); 
node = mxmlGetFirstChild(node); 
fprintf(stdout,"Element = %s\n",mxmlGetElement(node)); 
fprintf(stdout," Value = %s\n",mxmlGetText(node,0)); 
printf("\n"); 

printf("------- Sibling 1 of First child of Root\n"); 
node = mxmlGetNextSibling(node); 
fprintf(stdout,"Element = %s\n",mxmlGetElement(node)); 
fprintf(stdout," Value = %s\n",mxmlGetText(node,0)); 
printf("\n"); 

printf("------- Sibling 2 of First child of Root\n"); 
node = mxmlGetNextSibling(node); 
fprintf(stdout,"Element = %s\n",mxmlGetElement(node)); 
fprintf(stdout," Value = %s\n",mxmlGetText(node,0)); 
printf("\n"); 

printf("------- Sibling 3 of First child of Root\n"); 
node = mxmlGetNextSibling(node); 
fprintf(stdout,"Element = %s\n",mxmlGetElement(node)); 
fprintf(stdout," Value = %s\n",mxmlGetText(node,0)); 
printf("\n"); 

printf("------- Sibling 4 of First child of Root\n"); 
node = mxmlGetNextSibling(node); 
fprintf(stdout,"Element = %s\n",mxmlGetElement(node)); 
fprintf(stdout," Value = %s\n",mxmlGetText(node,0)); 
printf("\n"); 

결과 : 내가 생각

------- Root 
Element = root 
    Value = Root 

------- First child of Root 
Element = (null) 
    Value = Root 

------- Sibling 1 of First child of Root 
Element = (null) 
    Value = 

------- Sibling 2 of First child of Root 
Element = pai 
    Value = Pai_1 

------- Sibling 3 of First child of Root 
Element = (null) 
    Value = 

------- Sibling 4 of First child of Root 
Element = pai 
    Value = Pai_2 

을 아이와 부모 사이의 탐색의이 개념은 조금 이상합니다. 형제 사이에 (null) 값이있는 이유는 무엇입니까?

나는 ezxml로 돌아갈 것을 고려하고있다.

는 자식 노드를 얻기 위해 여기 ( http://www.minixml.org/mxml.html#3_7)에 설명 된 반복 기능을 사용하고자하는 것 같습니다

답변

4

주셔서 감사합니다.

편집 : 나는 첫 번째 자식 노드를 통해 아래로 반복이 쓴 그것을 잘 작동, mxmlGetFirstChildmxmlGetNextSibling을 사용 :

<!-- language: c --> 
mxml_node_t* node = mxmlLoadFile(NULL,f,MXML_TEXT_CALLBACK); 
while (node != NULL) 
{ 
    switch (mxmlGetType(node)) 
    { 
    case MXML_ELEMENT: 
    { 
     fprintf(stdout,"Element = %s\n",mxmlGetElement(node)); 
    } 
    break; 
    case MXML_TEXT: 
    { 
     fprintf(stdout," Value = %s\n",mxmlGetText(node,0)); 
    } 
    break; 
    default: 
    { 
    } 
    break; 
    } 
    mxml_node_t* next = mxmlGetFirstChild(node); 
    if (next != NULL) 
    { 
     node = next; 
    } 
    else 
    { 
     next = mxmlGetNextSibling(node); 
     if (next != NULL) 
     { 
     node = next; 
     } 
     else 
     { 
     node = next; 
     fprintf(stdout,"Done\n"); 
     } 
    } 
} 

가 생산 출력 :

Element = root 
Value = Root 
Value = 
Element = pai 
Value = Pai_1 
Value = 
Element = filho 
Value = Pai1,Filho1 

당신이 하나를 사용할 수 있습니다 내가 추정 getParent 함수를 사용하여 백업을 반복하거나 전체 파일을 반복하려는 경우 노드 포인터 스택을 사용하여 하위 노드로 이동하기 전에 마지막 노드를 저장하지 않아도됩니다. 두 개의 노드 유형에 대해서만 데이터를 처리/인쇄한다는 점에 유의하십시오. 다른 노드 유형에 포함되어있는 정보를 실험하기를 원할 것입니다. 해당 링크를 체크 아웃 -

** 편집 한 후 추가 편집은 **

나는 다른 사람이 libxml2 (http://xmlsoft.org/examples/index.html#xmlReader)를 시도하는 것이 바로 일전에 제안했다. xmlReader 예제는 사용법을 보여줍니다. 독자를 생성하고 노드를 반복하는 것은 매우 쉽습니다. 각 노드를 치면 형식이 맞는지 확인하고 (보통 ELEMENT, ATTRIBUTE, TEXTEND_ELEMENT) 이름이나 가치. 나는 mxml보다 훨씬 맘에 든다.

+0

예제 작업을 수행 할 수 없습니다. –

+0

컴파일되지 않았거나 예상 한 결과가 나오지 않았습니까? 무엇을 생산 했습니까? – rutgersmike

+0

I이 시퀀스를 수행 '노드 = xml_tree 단계;' '노드 = mxmlGetFirstChild (xml_tree)' '노드 = mxmlWalkNext (노드 xml_tree, MXML_DESCEND)' '의 printf ("> % S \ n"mxmlGetElement을 (node)); printf ("> % s \ n", mxmlGetText (node, NULL)); ' 결과 : (null) –

6

그냥 예를 들어 min-xml으로 시작하기 시작하고 좋은 예제가 부족하여 극도로 좌절했지만 필자는 XML 파일을 읽고 모든 부분을 보면서 완벽하지만보기 흉하지 만 빌려줬습니다. 태그 사이에 태그 이름, 속성 및 텍스트 값을 표시합니다. 종료 태그를 식별하는 방법을 모릅니다. 표준 xml 태그가 xml 파일 맨 위에 있는지 확인하십시오. stdio, stdlib, string .h 파일을 포함하십시오.

#include "mxml.h" 

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

     FILE *fp = NULL; 

     int k = 0; 

     mxml_node_t * tree = NULL; 
     mxml_node_t * node = NULL; 

     if (argc < 2){ 
      perror("Argument Required XML File "); 
      exit(1); 
     } 
     fp = fopen (argv[1], "r"); 
     if (fp){ 
      tree = mxmlLoadFile (NULL , fp , MXML_OPAQUE_CALLBACK); 
     }else { 
      perror("Could Not Open the File Provided"); 
      exit(1); 
     } 
     if (tree){ 
       for (node = mxmlFindElement(tree, tree,NULL,NULL, NULL,MXML_DESCEND); 
         node != NULL; 
         node=mxmlWalkNext (node, NULL, MXML_DESCEND) 
         //node = mxmlFindElement(node, tree, NULL,NULL,NULL,MXML_DESCEND) 
       ){ 
         if (node->type == MXML_ELEMENT) { 
          printf("MXML_ELEMENT Node <%s>:%d \n", node->value.element.name, node->value.element.num_attrs); 
          for (k = 0; k < node->value.element.num_attrs; k++){ 
           if (node->value.element.attrs){ 
            printf ("Attribute Name :: %s \n", node->value.element.attrs[k].name); 
            printf ("Attribute Value:: %s \n", node->value.element.attrs[k].value); 
           } 
           //if (!strncmp(node->value.element.name , "display-name", 12)){ 
           // printf(" String %s \n", (char*) node->child->value.text.string); 
           //} 
          } 
         } 
         else if (node->type == MXML_REAL){ 
          printf("MXML_REAL Node is %s \n", node->value.element.name); 
         } 
         else if(node->type == MXML_OPAQUE){ 
          printf("MXML_OPAQUE Node is %s \n", node->value.element.name); 
         } 
         else if(node->type == MXML_INTEGER){ 
          printf("MXML_INTEGER Node is %s \n", node->value.element.name); 
         } 
         else if(node->type == MXML_TEXT){ 
          printf("MXML_TEXT Node is %s \n", node->value.element.name); 
         } 
         else if(node->type == MXML_IGNORE){ 
          printf("MXML_IGNORE Node is %s \n", node->value.element.name); 
         } 
         else if(node->type == MXML_CUSTOM){ 
          printf("MXML_IGNORE Node is %s \n", node->value.element.name); 
         } 
         else { 
          printf("Type Default Node is %s \n", node->value.element.name); 
         } 
       } 
     } 
     if (tree){ 
      mxmlDelete(tree); 
     } 
     if (fp){ 
      fclose(fp); 
     } 
     return 0; 
} 
+0

이것을 추가해 주셔서 감사합니다! 나는 그것을 대단히 감사한다! –