Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

miniXML parsing C API

I'm trying parse the follow XML file:

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

I'm using the follow C code:

//... 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

How can I access the child of the root? Where my concept of access is wrong?

Thank you.


EDIT after @RutgersMike response

I expand your while loop to try understand the concept of 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");

The result this was:

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

I think this concept of navigation between child and parent a little strange. Why there are (null) values between sibling?

I am considering go back to ezxml.

Thank you

like image 574
Ricardo Crudo Avatar asked Dec 12 '22 04:12

Ricardo Crudo


1 Answers

Just starting playing with min-xml too and though I've been extremely frustrated by lack of good examples, I've borrowed and enhanced to give a decent but not perfect example of reading an XML file and seeing all the parts. It shows tag name, attributes, and text values between tags. Not sure how to identify ending tag. Make sure the standard xml tag is at top of xml file. Include stdio, stdlib, string .h files.

#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;
}
like image 116
Joe Programmer Avatar answered Dec 24 '22 10:12

Joe Programmer