Thread: Parse floats of "XML" like files?

  1. #1
    Registered User
    Join Date
    Mar 2017
    Posts
    4

    Parse floats of "XML" like files?

    Here i come with my weird question.

    I just made a little program to convert different kind of lines into another type and vise versa.

    Example:

    Code:
    CreateObject(11428,-2311.8000000,-1245.4000000,246.6000100,0.0000000,8.0000000,208.0000000,700.0);
    
    into CreateDynamicObject(11428,-2311.8000000,-1245.4000000,246.6000100,0.0000000,8.0000000,208.0000000,700.0);
    
    or CreateDynamicObject(11428,-2311.8000000,-1245.4000000,246.6000100,0.0000000,8.0000000,208.0000000,700.0);
    
    into  <object id="object" breakable="true" interior="17" alpha="255" model="3077" doublesided="false" scale="1" 
         dimension="0" posX="-957.5" posY="1888.1" posZ="4" rotX="0" rotY="0" rotZ="90"></object>
    The only missing step i need to complete is:

    Code:
     <object id="object (nf_blackboard) (4)" breakable="true" interior="17" alpha="255" model="3077" doublesided="false" 
        scale="1" dimension="0" posX="-957.5" posY="1888.1" posZ="4" rotX="0" rotY="0" rotZ="90"></object> 
    into CreateObject or CreateDyanmicObject
    Unfortunately i have no idea how to parse all the floats and integers. I read several tutorials about AsmXML, eXpat, Xerces-c, libxml and other parsers but its still too complicated to me.
    The given examples only had 1 value per line but here i have at least 6 floats per line!

    Thats what i currently made [C] #include <stdio.h> #include <asm-xml.h> /* (1) CreateObject (2) CreateDynami - Pastebin.com
    Is there a way to parse the values by using fscanf like i did for the other types? (CreateObject CreateDyanmicObject) or do i have to do something else like replacing all the other strings and using fscanf then?

    I would be glad to receive some help and maybe someone could show me how to use a parser in this case.
    Last edited by Salem; 03-02-2017 at 10:02 AM. Reason: wrapped long lines

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Well if your input isn't exactly XML, then using an XML parser is a waste of time, since XML has to be well-formed.

    How about pasting an actual copy of your input file, and write out by hand what you expect to see from it.
    Your XML object bares no resemblance to anything else in your post.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Mar 2017
    Posts
    4
    Thanks for your post!

    Unfortunately i always have a huge mass of these lines. At least 300000-500000 lines or around 40MB up to 100MB so thats not an option unfortunately

    Thats the kind of file i want to use as input
    Dont know if its XML

    Code:
    <map edf:definitions="editor_main">
        <object id="object (BinNt07_LA) (3)" breakable="true" interior="0" alpha="255" model="1337" doublesided="false" scale="1" dimension="0" posX="2503.64844" posY="-1572.14575" posZ="49.1593"></object>
    </map>
    So i want to parse model posX posY posZ rotX rotY rotZ and put it into this format
    CreateObject(model,posX,posY,posZ,rotX,rotY,rotZ); //object (BinNt07_LA) (3)
    Last edited by Knogle; 03-02-2017 at 10:35 AM.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Sorry, but not being able to provide a minimal worked example is a cop-out.

    That you have large files is irrelevant.
    If we can show you how to deal with 1 line, then dealing with 10000000 lines is just the same thing in a loop.

    There's always drop-box, unless your files are some commercial / state secret.


    > Thats the kind of file i want to use as input
    What?
    Your first post suggested XML was output, now it's input.

    OK, so given
    <object id="object (BinNt07_LA) (3)" breakable="true" interior="0" alpha="255" model="1337" doublesided="false" scale="1" dimension="0"
    posX="2503.64844" posY="-1572.14575" posZ="49.1593"></object>

    What sort of output are you expecting?


    > Dont know if its XML
    It looks like it.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    If you want help on your code, post it here within code tags, not pastebit or some other external site.

  6. #6
    Registered User
    Join Date
    Mar 2017
    Posts
    4
    So thats given <object id="object (BinNt07_LA) (3)" breakable="true" interior="0" alpha="255" model="1337" doublesided="false" scale="1" dimension="0"
    posX="2503.64844" posY="-1572.14575" posZ="49.1593"></object>

    I want to ignore everything except modelid="1337" posX="2503.64844" posY="-1572.14575" posZ="49.1593"

    I want to store these values into vars.
    Later i want to put them into this order
    CreateObject(modelid,posX,posY,posZ,..);

    So the result should be: CreateObject(1337,2503,64844,-1572.14575,49.1593);



    Okay no problem.
    Thats what i got at the moment

    Code:
    #include <stdio.h>
    
    /*
    (1) CreateObject
    (2) CreateDynamicObject
    (3) XML (MTA)
    
    
    */
    int inputtype=0;
    int outputtype=0;
    
    objecttype()
    {
        printf("\nValid Object types\n");
        printf("CreateObject: (1)\n");
        printf("CreateDynamicObject: (2)\n");
        printf("XML (MTA): (3)\n");
        
    }
    
    int main ( int argc, char *argv[] )
    {
        if ( argc != 2 ) 
        {
            
            printf( "Usage: %s [filename]\n", argv[0] );
        }
        else 
        {    
            FILE *fIn = fopen(argv[1], "r");
            if ( fIn == 0 )
            {
                printf( "Could not open file\n" );
            }
            else
            {    
                
                int inputtype=0;
                int i=0;
                int model = 0, items = 0;
                float pos[3] = {0}, rot[3] = {0};
                
                objecttype();
                printf("\nSpecify input object type:\n");
                scanf("%i",&inputtype);
                if(inputtype != 1 || inputtype != 2 || inputtype != 3)
                {
                    objecttype();
                }
                int outputtype=0;
                printf("\nSpecify output object type:\n");
                scanf("%i",&outputtype);
                if(outputtype != 1 || inputtype != 2 || inputtype != 3)
                {
                    objecttype();
                }
                if(outputtype == inputtype)
                {
                    printf("You cannot convert objects into the same type!");
                }
                else
                {
                    
    
                    
                    FILE *fOut = fopen("output.txt", "wb");
                    
                    
                    if(inputtype == 1)//CreateObject Inputtype
                    {
                        while ((items = fscanf(fIn, "%*[^-0123456789]%d%*[,]%f%*[,]%f%*[,]%f%*[,]%f%*[,]%f%*[,]%f%*s", &model, &pos[0], &pos[1], &pos[2], &rot[0], &rot[1], &rot[2])) != EOF)
                        {    
                            if(outputtype == 3)
                            {
                                if (items == 7)
                                {
                                    fprintf(fOut, "<object id=\"object (Konvert)(%d)\" breakable=\"true\" interior=\"0\" collisions=\"true\" alpha=\"255\" model=\"%d\" doublesided=\"false\" scale=\"1\" dimension=\"0\" posX=\"%.7g\" posY=\"%.7g\" posZ=\"%.7g\" rotX=\"%.7g\" rotY=\"%.7g\" rotZ=\"%.7g\"></object>\n", i,model, pos[0], pos[1], pos[2], rot[0], rot[1], rot[2]);
                                    
                                }
                            }
                            if(outputtype == 2)
                            {
                                if (items == 7)
                                {
                                    fprintf(fOut, "CreateDynamicObject(%d,%f,%f,%f,%f,%f,%f);// Object (%d)\n",model, pos[0], pos[1], pos[2], rot[0], rot[1], rot[2],i);
                                    
                                }
                            }
    
                            i++;
                        }
                        
                        
                    }
                    if(inputtype == 2)//CreateDynamicObject Inputtype
                    {
                        while ((items = fscanf(fIn, "%*[^-0123456789]%d%*[,]%f%*[,]%f%*[,]%f%*[,]%f%*[,]%f%*[,]%f%*s", &model, &pos[0], &pos[1], &pos[2], &rot[0], &rot[1], &rot[2])) != EOF)
                        {    
                            if(outputtype == 3)
                            {
                                if (items == 7)
                                {
                                    fprintf(fOut, "<object id=\"object (Konvert)(%d)\" breakable=\"true\" interior=\"0\" collisions=\"true\" alpha=\"255\" model=\"%d\" doublesided=\"false\" scale=\"1\" dimension=\"0\" posX=\"%.7g\" posY=\"%.7g\" posZ=\"%.7g\" rotX=\"%.7g\" rotY=\"%.7g\" rotZ=\"%.7g\"></object>\n", i,model, pos[0], pos[1], pos[2], rot[0], rot[1], rot[2]);
                                    
                                }
                            }
                            if(outputtype == 1)
                            {
                                if (items == 7)
                                {
                                    fprintf(fOut, "CreateObject(%d,%f,%f,%f,%f,%f,%f);// Object (%d)\n",model, pos[0], pos[1], pos[2], rot[0], rot[1], rot[2],i);
                                    
                                }
                            }
    
                            i++;
                        }
                        
                        
                    }
                    if(inputtype == 3)//XML Inputtype !!!! NOTE!!!! NOT WORKING
                    {
                        while ((items = fscanf(fIn, "%*[^-0123456789 a-zA-Z ><\]%d%f%f%f%f%f%f%",&model, &pos[0], &pos[1], &pos[2], &rot[0], &rot[1], &rot[2])) != EOF)
                        {    
                            if(outputtype == 3)
                            {
                                if (items == 7)
                                {
                                    fprintf(fOut, "<object id=\"object (Konvert)(%d)\" breakable=\"true\" interior=\"0\" collisions=\"true\" alpha=\"255\" model=\"%d\" doublesided=\"false\" scale=\"1\" dimension=\"0\" posX=\"%.7g\" posY=\"%.7g\" posZ=\"%.7g\" rotX=\"%.7g\" rotY=\"%.7g\" rotZ=\"%.7g\"></object>\n", i,model, pos[0], pos[1], pos[2], rot[0], rot[1], rot[2]);
                                    
                                }
                            }
                            if(outputtype == 2)
                            {
                                if (items == 7)
                                {
                                    fprintf(fOut, "CreateDynamicObjectObject(%d,%f,%f,%f,%f,%f,%f);// Object (%d)\n",model, pos[0], pos[1], pos[2], rot[0], rot[1], rot[2],i);
                                    
                                }
                            }
                            if(outputtype == 1)
                            {
                                if (items == 7)
                                {
                                    fprintf(fOut, "CreateObject(%d,%f,%f,%f,%f,%f,%f);// Object (%d)\n",model, pos[0], pos[1], pos[2], rot[0], rot[1], rot[2],i);
                                    
                                }
                            }
    
                            i++;
                        }
                        
                        
                    }
                    fclose(fOut);
                    fclose(fIn);
                    printf("%d Objekt(e) konvertiert.\n\n",i);
                    return 0;
                }
            }
        }
    }
    I hope my second post is being activated as well heh.
    Last edited by Knogle; 03-02-2017 at 02:15 PM.

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Cribbed from http://veillard.com/XML/example/gjobread.c
    API reference List of function manipulating types in libxml2

    The input XML
    Code:
    <?xml version="1.0"?>
    <thing xmlns:edf="http://edf.com">
    <map edf:definitions="editor_main">
        <object id="object (BinNt07_LA) (3)" breakable="true" interior="0" alpha="255" model="1337" doublesided="false" scale="1" dimension="0" posX="2503.64844" posY="-1572.14575" posZ="49.1593"></object>
    </map>
    </thing>
    The code
    Code:
    #include <stdio.h>
    #include <libxml/xmlmemory.h>
    #include <libxml/parser.h>
    
    void walker(xmlNodePtr cur,int level) {
      while ( cur != NULL ) {
        printf("%*s%s\n",level*4,"",cur->name);
        if ( xmlStrcmp(cur->name, (const xmlChar *)"object") == 0 ) {
          xmlChar *p = xmlGetProp(cur, (const xmlChar *)"id");
          if ( p ) {
            printf("%*s object ID=%s\n",level*4+4,"",p);
          }
        }
        if ( cur->xmlChildrenNode ) {
          walker(cur->xmlChildrenNode,level+1);
        }
        cur = cur->next;
      }
    }
    
    void *parseModelFile( const char *filename ) {
        xmlDocPtr doc;
        xmlNodePtr cur;
    
        doc = xmlParseFile(filename);
        if (doc == NULL) return(NULL);
        
        cur = xmlDocGetRootElement(doc);
        if (cur == NULL) {
            fprintf(stderr,"empty document\n");
    	xmlFreeDoc(doc);
    	return(NULL);
        }
        walker(cur->xmlChildrenNode,0);
        xmlFreeDoc(doc);
        return "";
    }
    
    int main(int argc, char **argv) {
     #ifdef LIBXML_SAX1_ENABLED
        int i;
        /* COMPAT: Do not genrate nodes for formatting spaces */
        xmlKeepBlanksDefault(0);
    
        for (i = 1; i < argc ; i++) {
    	if ( !parseModelFile(argv[i]) ) {
                fprintf(stderr,"Error parsing %s\n",argv[i]);
            }
        }
    
        /* Clean up everything else before quitting. */
        xmlCleanupParser();
    #else
        printf(stderr,"LIBXML_SAX1_ENABLED needed\n");
    #endif
        return 0;
    }
    Compile and run
    Code:
    $ gcc -Wall -I/usr/include/libxml2 foo.c -lxml2
    $ ./a.out foo.xml
    map
        object
             object ID=object (BinNt07_LA) (3)
    $
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  8. #8
    Registered User
    Join Date
    Mar 2017
    Posts
    4
    Thanks for your reply, it worked!

    I still got one question left.. if i have a single line with following content divisible="1", is there a simple way to "extract" the 1 between both quotation marks? Possible with sscanf? I dont know how to ignore the first string and both quotation marks with sscanf, maybe you can help.
    Expected output should be 1 without ""

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Look at the output I posted.
    Do you see any quote marks?

    Attribute values are strings, with the quotation removed.

    So yes, you can parse it directly with sscanf.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User
    Join Date
    May 2012
    Posts
    505
    Quote Originally Posted by Knogle View Post
    Here i come with my weird question.

    I just made a little program to convert different kind of lines into another type and vise versa.

    Code:
     <object id="object (nf_blackboard) (4)" breakable="true" interior="17" alpha="255" model="3077" doublesided="false" 
        scale="1" dimension="0" posX="-957.5" posY="1888.1" posZ="4" rotX="0" rotY="0" rotZ="90"></object> 
    into CreateObject or CreateDyanmicObject
    Unfortunately i have no idea how to parse all the floats and integers
    Parsing floats and integers is easy, just call strtod for a float and strtol for an integer. The hard part is getting the XML hierarchical structure successfully navigated

    I suggest you take a look at my "vanilla" XML parser. It's not a proper XML parser, just something which which will parse simple XML.

    Vanilla XML Parser
    I'm the author of MiniBasic: How to write a script interpreter and Basic Algorithms
    Visit my website for lots of associated C programming resources.
    https://github.com/MalcolmMcLean


Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 4
    Last Post: 08-24-2014, 08:26 PM
  2. "itoa"-"_itoa" , "inp"-"_inp", Why some functions have "
    By L.O.K. in forum Windows Programming
    Replies: 5
    Last Post: 12-08-2002, 08:25 AM
  3. "CWnd"-"HWnd","CBitmap"-"HBitmap"...., What is mean by "
    By L.O.K. in forum Windows Programming
    Replies: 2
    Last Post: 12-04-2002, 07:59 AM
  4. I'm confused about "parse error"
    By Chizzlah in forum C++ Programming
    Replies: 12
    Last Post: 09-04-2002, 02:45 PM
  5. problem with functions and "parse errors"
    By bart in forum C++ Programming
    Replies: 3
    Last Post: 08-27-2001, 08:52 AM

Tags for this Thread