Expat, decision making on element-name

Discussion in 'C Programming' started by Maarten Verhage, Apr 30, 2004.

  1. Hi All,

    I've made a modified version of the Expat elements.c example. What I
    want the program to do is to recognize a hardcoded
    element-name/tag-name and then execute some code which has access to
    the data(e.g. "Maarten Verhage" in XML file).

    The current situation (problem) is:

    1. The XML parser calls the function startElement when it finds a tag,
    in this function I don't have access to the data between the tags.

    2. The XML parser calls the function charHandler when it finds data,
    in this function I don't have access to the tag-name.

    Thank you!

    -- below is the code I have now

    -- start of XML file
    <?xml version="1.0"?>
    <person>
    <name>Maarten Verhage</name>
    <age>24</age>
    </person>
    -- end of XML file

    -- start of C file
    #include <stdio.h>
    #include <conio.h>
    #include "expat.h"

    static void XMLCALL startElement(void *userData, const char *name,
    const char **atts)
    {
    int i;
    int *depthPtr = userData;

    for (i = 0; i < *depthPtr; i++)
    {
    putchar('\t');
    }
    // print elementname
    puts(name);

    *depthPtr += 1;
    }

    static void XMLCALL endElement(void *userData, const char *name)
    {
    int *depthPtr = userData;
    *depthPtr -= 1;
    }

    static void XMLCALL charHandler(void *userData, const XML_Char *s, int
    len)
    {
    int i;
    for (i=0; i < len; i++)
    {
    fprintf(stdout, "%c", s);
    }
    }

    int main(int argc, char *argv[])
    {
    FILE *xmlfile;
    char buf[BUFSIZ];
    XML_Parser parser = XML_ParserCreate(NULL);
    int done;
    int depth = 0;
    XML_SetUserData(parser, &depth);
    XML_SetElementHandler(parser, startElement, endElement);
    XML_SetCharacterDataHandler(parser, charHandler);

    // open XML file
    if ((xmlfile = fopen("xml_test.xml", "r")) == NULL)
    {
    fprintf(stderr, "Error opening xml_test.xml\n");
    getch();
    return -1;
    }

    do
    {
    size_t len = fread(buf, 1, sizeof(buf), xmlfile);
    done = len < sizeof(buf);
    if (XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR)
    {
    fprintf(stderr,
    "%s at line %d\n",
    XML_ErrorString(XML_GetErrorCode(parser)),
    XML_GetCurrentLineNumber(parser));
    return 1;
    }
    } while (!done);

    XML_ParserFree(parser);

    // close the XML file
    fclose(xmlfile);

    getch();
    return 0;
    }
    -- end of C file
     
    Maarten Verhage, Apr 30, 2004
    #1
    1. Advertising

  2. Maarten Verhage

    Peter Dunker Guest

    "Maarten Verhage" <> schrieb im Newsbeitrag
    news:...
    > Hi All,
    >
    > I've made a modified version of the Expat elements.c example. What I
    > want the program to do is to recognize a hardcoded
    > element-name/tag-name and then execute some code which has access to
    > the data(e.g. "Maarten Verhage" in XML file).
    >
    > The current situation (problem) is:
    >
    > 1. The XML parser calls the function startElement when it finds a

    tag,
    > in this function I don't have access to the data between the tags.
    >
    > 2. The XML parser calls the function charHandler when it finds data,
    > in this function I don't have access to the tag-name.
    >
    > Thank you!



    You can use other UserData, maybe a structure where depth is inside.
    I never tryed it but I think that can work.

    typedef struct
    {
    int depth;
    int found;
    }S_MY_DATA,*PS_MY_DATA;


    >
    > -- start of XML file
    > <?xml version="1.0"?>
    > <person>
    > <name>Maarten Verhage</name>
    > <age>24</age>
    > </person>
    > -- end of XML file
    >
    > -- start of C file
    > #include <stdio.h>
    > #include <conio.h>
    > #include "expat.h"
    >
    > static void XMLCALL startElement(void *userData, const char *name,
    > const char **atts)
    > {
    > int i;


    PS_MY_DATA pMy = userData;


    >
    > for (i = 0; i < *depthPtr; i++)
    > {
    > putchar('\t');
    > }
    > // print elementname
    > puts(name);

    //compare the name and set found to 1

    >
    > *depthPtr += 1;
    > }
    >
    > static void XMLCALL endElement(void *userData, const char *name)
    > {
    > int *depthPtr = userData;
    > *depthPtr -= 1;
    > }
    >
    > static void XMLCALL charHandler(void *userData, const XML_Char *s,

    int
    > len)
    > {
    > int i;


    PS_MY_DATA pMy = userData;
    //if found in pMy is 1 then print and set found to 0
    //or set found to 0 inside the endElement function


    > for (i=0; i < len; i++)
    > {
    > fprintf(stdout, "%c", s);
    > }
    > }
    >
    > int main(int argc, char *argv[])
    > {
    > FILE *xmlfile;
    > char buf[BUFSIZ];


    PS_MY_DATA pMyData;
    pMyData = malloc(sizeof(S_MY_DATA));
    pMyData->found = 0;
    pMyData->depth = 0;

    > XML_Parser parser = XML_ParserCreate(NULL);
    > int done;


    // int depth = 0;
    XML_SetUserData(parser, pMyData);
    ^^^^^^^^
    > XML_SetElementHandler(parser, startElement, endElement);
    > XML_SetCharacterDataHandler(parser, charHandler);
    >
    > // open XML file
    > if ((xmlfile = fopen("xml_test.xml", "r")) == NULL)
    > {
    > fprintf(stderr, "Error opening xml_test.xml\n");
    > getch();
    > return -1;
    > }
    >
    > do
    > {
    > size_t len = fread(buf, 1, sizeof(buf), xmlfile);
    > done = len < sizeof(buf);
    > if (XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR)
    > {
    > fprintf(stderr,
    > "%s at line %d\n",
    > XML_ErrorString(XML_GetErrorCode(parser)),
    > XML_GetCurrentLineNumber(parser));
    > return 1;
    > }
    > } while (!done);
    >
    > XML_ParserFree(parser);
    >
    > // close the XML file
    > fclose(xmlfile);
    >
    > getch();
    > return 0;
    > }
    > -- end of C file


    Peter
     
    Peter Dunker, Apr 30, 2004
    #2
    1. Advertising

  3. Maarten Verhage

    SM Ryan Guest

    (Maarten Verhage) wrote:
    # Hi All,
    #
    # I've made a modified version of the Expat elements.c example. What I
    # want the program to do is to recognize a hardcoded
    # element-name/tag-name and then execute some code which has access to
    # the data(e.g. "Maarten Verhage" in XML file).
    #
    # The current situation (problem) is:
    #
    # 1. The XML parser calls the function startElement when it finds a tag,
    # in this function I don't have access to the data between the tags.
    #
    # 2. The XML parser calls the function charHandler when it finds data,
    # in this function I don't have access to the tag-name.

    # int *depthPtr = userData;

    Instead if just an integer, set the user data to a structure, and pass
    information among the callbacks with this structure.
    http://www.rawbw.com/~wyrmwif/html/wyrm-expat.html#16
    is an example of the kind of callback structure that can be used.

    --
    SM Ryan http://www.rawbw.com/~wyrmwif/
    This is one wacky game show.
     
    SM Ryan, Apr 30, 2004
    #3
  4. Thank you both for your suggestions!

    For everybody who had similar problems like me, here is a code sample,
    which also looks into the arguments of the elements. There should be a
    better way of programming like this, but my C knowledge is limited.

    -- start det_tagname.c file
    #include <stdio.h>
    #include <conio.h>
    #include <string.h>
    #include "expat.h"

    #define XMLFILENAME "master.smil"

    typedef struct
    {
    int found;
    char elementName[10];
    char attrElementName[3][10];
    char attrData[3][20];
    int numberAttr;
    } S_MY_DATA,*PS_MY_DATA;

    static void XMLCALL startElement(void *userData, const char *name,
    const char **atts)
    {
    int word = 0;
    //int character = 0;
    PS_MY_DATA pMy = userData;

    // compare the name and set found to 1
    if (strcmp(name, "ref") == 0)
    {
    pMy->found = 1;
    strcpy(pMy->elementName, name);

    while(*atts) // element
    {
    sprintf(pMy->attrElementName[word],"%s", *atts++);
    sprintf(pMy->attrData[word],"%s", *atts++);
    word++;
    }
    pMy->numberAttr = word;
    }
    }



    static void XMLCALL endElement(void *userData, const char *name)
    {
    }

    static void XMLCALL charHandler(void *userData, const XML_Char *s, int
    len)
    {
    int i;
    int currentAttr = 0;

    PS_MY_DATA pMy = userData;
    // if found in pMy is 1 then print
    if (pMy->found == 1)
    {
    fprintf(stdout, "\n\nelementName 0: %s", pMy->elementName);
    for (i = 0; i < len; i++)
    {
    fprintf(stdout, "%c", s);
    }

    for (currentAttr = 0; currentAttr < pMy->numberAttr; currentAttr++)
    {
    fprintf(stdout,
    "attrElementName %d: %s",
    currentAttr,
    pMy->attrElementName[currentAttr]);
    fprintf(stdout,
    "\nattrData %d: %s\n",
    currentAttr,
    pMy->attrData[currentAttr]);
    } // end loop
    pMy->found = 0;
    }
    }

    int main(int argc, char *argv[])
    {
    FILE *xmlfile;
    char buf[BUFSIZ];
    PS_MY_DATA pMyData;
    XML_Parser parser = XML_ParserCreate(NULL);

    int done;

    pMyData = malloc(sizeof(S_MY_DATA));
    pMyData->found = 0;
    pMyData->numberAttr = 0;

    XML_SetUserData(parser, pMyData);
    XML_SetElementHandler(parser, startElement, endElement);
    XML_SetCharacterDataHandler(parser, charHandler);

    // open XML file
    if ((xmlfile = fopen(XMLFILENAME, "r")) == NULL)
    {
    fprintf(stderr, "Error opening XML file\n");
    getch();
    return -1;
    }

    do
    {
    size_t len = fread(buf, 1, sizeof(buf), xmlfile);
    done = len < sizeof(buf);
    if (XML_Parse(parser, buf, len, done) == XML_STATUS_ERROR)
    {
    fprintf(stderr,
    "%s at line %d\n",
    XML_ErrorString(XML_GetErrorCode(parser)),
    XML_GetCurrentLineNumber(parser));
    return 1;
    }
    } while (!done);

    XML_ParserFree(parser);

    // close the XML file
    fclose(xmlfile);

    free(pMyData);

    getch();
    return 0;
    }
    -- end det_tagname.c file
     
    Maarten Verhage, May 7, 2004
    #4
  5. Maarten Verhage

    CBFalconer Guest

    Maarten Verhage wrote:
    >
    > Thank you both for your suggestions!


    Who, about what? No quotations, no attributions, etc.

    >
    > For everybody who had similar problems like me, here is a code
    > sample, which also looks into the arguments of the elements.
    > There should be a better way of programming like this, but my C
    > knowledge is limited.
    >
    > -- start det_tagname.c file
    > #include <stdio.h>
    > #include <conio.h>


    No such standard include file.

    > #include <string.h>
    > #include "expat.h"


    This is not shown here.
    >
    > #define XMLFILENAME "master.smil"
    >
    > typedef struct
    > {
    > int found;
    > char elementName[10];
    > char attrElementName[3][10];
    > char attrData[3][20];
    > int numberAttr;
    > } S_MY_DATA,*PS_MY_DATA;
    >
    > static void XMLCALL startElement(void *userData, const char *name,

    ^^^^^^^
    Undefined type ^^^

    > const char **atts)
    > {
    > int word = 0;
    > //int character = 0;


    Do not use // comments unless you are using C99. Do not use them
    in any case in usenet postings.

    Your postings on c.l.c should be completely understandable with
    only the C standard as auxiliary information.

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
     
    CBFalconer, May 7, 2004
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. ouadid abdelkarim
    Replies:
    0
    Views:
    2,040
    ouadid abdelkarim
    Jul 10, 2003
  2. Jim Adams

    Q&A Decision Tree in ASP.Net

    Jim Adams, Apr 27, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    776
    Jeff Bennett
    May 16, 2004
  3. sharan
    Replies:
    1
    Views:
    735
    Pavel Lepin
    Oct 26, 2007
  4. HANM
    Replies:
    2
    Views:
    762
    Joseph Kesselman
    Jan 29, 2008
  5. Replies:
    6
    Views:
    211
Loading...

Share This Page