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 

Как я могу получить доступ к ребенку корня? Где моя концепция доступа неверна?

спасибо.


EDIT после ответа @RutgersMike

Я расширить время цикла, чтобы попытаться понять концепцию minixml:

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 

Я думаю, эта концепция навигации между ребенком и родителем немного странная. Почему существуют (нулевые) значения между родственниками?

Я рассматриваю возможность вернуться к ezxml.

Спасибо

ответ

4

Похоже, что вы хотите использовать функции итерации, описанные здесь (http://www.minixml.org/mxml.html#3_7), чтобы получить дочерние узлы.

EDIT: Я написал это итерацию вниз через первый дочерний узел, и он прекрасно работает, используется mxmlGetFirstChild и mxmlGetNextSibling:

<!-- 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 для повторного выполнения резервного копирования или сохранения последнего узла перед погружением в дочерний элемент, используя стек указателей узлов, если вы хотите итерации по всему файлу. Обратите внимание, что я обрабатываю/печатаю данные только для двух типов узлов - вам нужно поэкспериментировать, чтобы увидеть, что содержат другие типы узлов, если вам нужна эта информация.

** MORE EDIT после редактирования **

Я предложил только на другой день, что кто-то еще попробовать libxml2 (http://xmlsoft.org/examples/index.html#xmlReader) - проверить, что соединение вне. Пример xmlReader показывает использование. Это невероятно легко создать читателя и перебрать узлы - когда вы нажимаете на каждый узел, просто проверяйте его тип, чтобы быть уверенным, что это ваш вопрос (обычно ELEMENT, ATTRIBUTE, TEXT и END_ELEMENT), а затем вытаскивать либо имя, либо Значение. Мне это нравится намного лучше, чем mxml.

+0

Я не мог сделать ваш пример работы. –

+0

Не скомпилировал ли он или не дал ожидаемого результата? Что он произвел? – rutgersmike

+0

я эту последовательность: 'узла = xml_tree;' 'узла = mxmlGetFirstChild (xml_tree);' 'узел = mxmlWalkNext (узел, xml_tree, MXML_DESCEND);' 'Е (">% s \ п", 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

Благодарим вас за добавление! Я очень ценю это! –