Simple XML tag validator

Discussion in 'C++' started by kapa, Apr 8, 2007.

  1. kapa

    kapa Guest

    Hi

    The program is suppose to search tags from xml file and determine does
    every tag have a pair, meaning if there is a <start> there must be
    </start>, and make count how many there is that particular type. Or in
    case <foo/> just take notice and count.

    Ok, I have managed to make the program return the tags like below, and
    return the value how many tags there is:

    things
    basket
    fruit
    /fruit
    bug/
    /basket
    foo/
    /things


    Now my problem is that I really don't now how to compare is there a
    match, and if found how to make sure the found pair is no longer compared.

    Now I have put the tags into a two-dimensional array. But I'm wondering
    should I use stack or what, and how? My head is empty at the moment, so
    any help would be appreciate.

    bool getTag( ifstream &in, char tag[], int taglen ) ;
    void cleanTag( char tag[], int taglen, int &count ) ;
    void printTags( char tags[][30], int count ) ;

    int main()
    {
    int count = 0 ;
    char tag[150] ;
    char tags[50][30];

    ifstream in ;
    in.open( "Test1.xml" ) ;

    if( !in.is_open() )
    cout << "Can't open the file!\n" ;
    else
    {
    while( getTag( in, tag, 150 ) )
    {
    cleanTag( tag, 30, count ) ;
    if( strlen( tag ) != 0 )
    strcpy( tags[count-1], tag ) ;
    }
    }
    printTags( tags, count ) ;
    return 0 ;
    }

    void printTags( char tags[][30], int count )
    {
    for( int i=0; i<count; i++ )
    {
    for( int j=0; tags[j] != '\0'; j++ )
    {
    cout << tags[j] ;
    }
    cout << endl ;
    }
    }
     
    kapa, Apr 8, 2007
    #1
    1. Advertising

  2. kapa

    Zeppe Guest

    kapa wrote:
    > Hi


    hi!

    > The program is suppose to search tags from xml file and determine does
    > every tag have a pair, meaning if there is a <start> there must be
    > </start>, and make count how many there is that particular type. Or in
    > case <foo/> just take notice and count.
    >
    > Ok, I have managed to make the program return the tags like below, and
    > return the value how many tags there is:
    >
    > things
    > basket
    > fruit
    > /fruit
    > bug/
    > /basket
    > foo/
    > /things
    >
    >
    > Now my problem is that I really don't now how to compare is there a
    > match, and if found how to make sure the found pair is no longer compared.


    If you just want to check the pairs, a simple method would be this:
    * you have threee types of tags: opening (<foo>), closing (</foo>),
    and alone (<foo />).
    * you create a stack of tag that are opened and that are waiting for
    the closing tag.
    * for each tag, you read it:
    - if the tag is alone, ignore it and go ahead;
    - if the tag is opening, you put it in the top of the stack and go ahead;
    - if the tag is closing, it has to match to the opening tag at the
    top of the stack. If it does, everything is ok and you pop the top of
    the stack and go ahead. Otherwise (empty stack or unmatching elements)
    there is an error and the xml is badly formatted.

    Example:
    > things
    > basket
    > fruit
    > /fruit
    > bug/
    > /basket
    > foo/
    > /things


    step1: insert things

    things <-

    step2: insert basket

    basket <-
    things

    step3: insert fruit

    fruit <-
    basket
    things

    step 4: /fruit matches with the top, remove fruit

    basket <-
    things

    step5: /bug doesn't match with the top: there is an error

    Of course, now everything is bad and you should end your analysis. If
    you want to implement some intelligence and some reasoning on the error
    cause, it becomes more complicated.

    > Now I have put the tags into a two-dimensional array. But I'm wondering
    > should I use stack or what, and how? My head is empty at the moment, so
    > any help would be appreciate.


    The stack was a good intuition! Use that one defined by the stl
    (#include <stack>).

    Another good idea would be to define a simple class for the problem

    class Tag
    {
    public:
    enum Type {OPENING, CLOSING, ALONE};
    public:
    Tag(Type t, std::string name);

    std::string GetName(); // returns the pure name

    Type GetType(); // returns the type of the tag

    bool IsMatching(const Tag& t); // returns true if t is closing and
    this is opening with the same name and viceversa
    };

    Good work!

    Bye,

    Zeppe
     
    Zeppe, Apr 8, 2007
    #2
    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. shruds
    Replies:
    1
    Views:
    853
    John C. Bollinger
    Jan 27, 2006
  2. Replies:
    4
    Views:
    444
  3. Replies:
    4
    Views:
    908
    Richter~9.6
    Feb 13, 2007
  4. Erik Wasser
    Replies:
    5
    Views:
    468
    Peter J. Holzer
    Mar 5, 2006
  5. P
    Replies:
    7
    Views:
    141
    Tad McClellan
    Jan 12, 2007
Loading...

Share This Page