Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

mediatomn XML parser using pure JS 1.8.0

Anonymous
2013-02-18
2013-05-30

  • Anonymous
    2013-02-18

    I wrote a simple & light XML parser by myself for those like me who needs to parse them with JS_HAS_FILE_OBJECT=1
    Maybe libjs 1.8.5 do parse XML, but I think it to be too much complex & am pretty sure it cannot be more efficient than my parser.
    Plus with this method your XML files HAVE to have a tag with the movie extension. Since no media manager do that with their generated XML, you would have to pass another script BEFORE scanning the files with mediatomb. Too much work with that.

    0) XML extract generated with MCM : www.mediacentermaster.com

    <?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?>
    <movie xmlns:xsi=\\\"xxxxxxxxx\\\" xmlns:xsd=\\\"xxxxxxxxxxx\\\">
    <title>title</title>
    <genre>Sci-Fi</genre>
    <studio>Metro-Goldwyn-Mayer (MGM)</studio>
    <credits>John Wyndham / Stirling Silliphant / Ronald Kinnoch / Wolf Rilla</credits>
    <emptytag></emptytag>
    <director>Wolf Rilla</director>
    <actor>
        <name>George Sanders</name>
        <role>Gordon Zellaby</role>
    </actor>
    <actor>
        <name>Barbara Shelley</name>
        <role>Anthea Zellaby</role>
    </actor>
    (...)
    

    1a) libjs compiled with JS_HAS_FILE_OBJECT=1 :
    function to return every line from xml in an array

    function getArrayFromNfoFile(object)
    {
    var file = new File(object.location.replace(/(\\\\.\\\\w+)$/g,\\\'.nfo\\\'));
    if (file.exists) {
        file.open(\\\"read\\\", \\\"text\\\");
        xml_array = file.readAll();
        file.close();
        return xml_array;
    } else return null;
    }
    

    1b) second solution : same function but with playlist.js, only if the movie file extension is included in one of the tag, useless otherwise :

    function treat_nfo()
    {
        return;
        var xml_array = [];
        var line = readln();
        do
        {
        xml_array.concat(line);
        line = readln();
        }
        while (line);
        var movie = parseNfoArray(xml_array);
    }
    

    2) function for an Actor object which contain 2 or more properties (tags with sub-tags) :

    function Actor(name, role)
    {
        this.name = name;
        this.role = role;
    }
    

    3) function to parse the XML array :

    function parseNfoArray(xml_array)
    {
        if (!xml_array) return null;
        var movie = new Object();
        movie.actors = [];
        // remember we don\\\'t want the first line
        for (i = 2; i < xml_array.length; i++)
        {
            // http://jsperf.com/exec-vs-match-vs-test/3
            // http://www.pagecolumn.com/tool/regtest.htm
            // http://stackoverflow.com/users/121483/sjuul-janssen
            // myArray = \\\'<id moviedb=\\\"imdb\\\">xxx</id>\\\'.match(/(<[^>]+>)([^<]+)(<[^>]+>)/); will result in :
            // myArray[0] = \\\"<id>xxx</id>\\\"
            // myArray[1] = \\\"<id>\\\"
            // myArray[2] = \\\"xxx\\\"
            // myArray[3] = \\\"</id>\\\"
    
            // if the xml tag is empty, myArray is empty :
            tag = xml_array[i].match(/(<[^>]+>)([^<]+)(<[^>]+>)/);
            // if tag is empty, maybe it\\\'s a multiple sub-tags case :
            if (!tag) tag = xml_array[i].match(/\\\\s+<(\\\\w+)>$/);
            if (!tag) continue;
            switch (tag[1])
            {
            case \\\'<title>\\\':
                movie.title= tag[2];
                break;
            case \\\'<anytag>\\\':
                movie.anytag= tag[2];
                break;
            case (...)
    
            case \\\'actor\\\':
                // tag with sub-tags whose sub-tags quantity is known : 
                i++;
                tag = xml_array[i].match(/(<[^>]+>)([^<]+)(<[^>]+>)/);
                if (\\\'<name>\\\' == tag[1]) name = tag[2]; else role = tag[2];
                i++;
                tag = xml_array[i].match(/(<[^>]+>)([^<]+)(<[^>]+>)/);
                if (\\\'<role>\\\' == tag[1]) role = tag[2]; else name = tag[2];
                movie.actors.push(new Actor(name, role));
                break;
            default:
                break;
            }
        }
        return movie;
    }
    

    here you go ;)

    you got now obj (the movie), and movie, an object with properties you can treat to build your tree !

    for Actors you can parse them like this :

    while (movie.actors.length > 0) {actor = movie.actors.shift(); doSmthgWith(actor);}
    

    thanks to ???