Search code examples
xml-parsingasp-classic

How do I iterate xml files that have many of the same tag per record?


I'm working on an old classic asp system that receives an xml file from another system that has recently changed the format of the xml file. It contains a video library summary I need to parse.

Sample xml as follows:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<videodb>
    <version>1</version>
    <movie>
        <title>3 Days to Kill</title>
        <ratings>
            <rating name="themoviedb" max="10" default="true">
                <value>6.000000</value>
                <votes>1416</votes>
            </rating>
        </ratings>
        <plot>A dangerous international spy... blah blah blah</plot>
        <runtime>113</runtime>
        <mpaa>Rated PG-13</mpaa>
        <id>tt2172934</id>
        <uniqueid type="imdb" default="true">tt2172934</uniqueid>
        <uniqueid type="tmdb">192102</uniqueid>
        <genre>Action</genre>
        <genre>Drama</genre>
        <genre>Thriller</genre>
        <genre>Crime</genre>
        <year>2014</year>
        <status></status>
        <code></code>
        <trailer></trailer>
        <actor>
            <name>Kevin Costner</name>
            <role>Ethan Renner</role>
        </actor>
        <actor>
            <name>Amber Heard</name>
            <role>Vivi Delay</role>
        </actor>
        <dateadded>2014-12-21 14:31:07</dateadded>
    </movie>
    <movie>
        <title>47 Ronin</title>
        <ratings>
            <rating name="themoviedb" max="10" default="true">
                <value>6.000000</value>
                <votes>2324</votes>
            </rating>
        </ratings>
        <plot>Kai—an outcast—joins Oishi, the leader of 47 outcast samurai...blah blah blah</plot>
        <runtime>119</runtime>
        <mpaa>Rated PG-13</mpaa>
        <playcount>1</playcount>
        <lastplayed>2020-03-24</lastplayed>
        <id>tt1335975</id>
        <uniqueid type="imdb" default="true">tt1335975</uniqueid>
        <uniqueid type="tmdb">64686</uniqueid>
        <genre>Drama</genre>
        <genre>Action</genre>
        <genre>Adventure</genre>
        <genre>Fantasy</genre>
        <year>2013</year>
        <trailer></trailer>
        <actor>
            <name>Keanu Reeves</name>
            <role>Kai</role>
        </actor>
        <actor>
            <name>Hiroyuki Sanada</name>
            <role>Kuranosuke Ôishi</role>
        </actor>
        <dateadded>2014-12-21 22:15:42</dateadded>
    </movie>
</videodb>

My asp code is as follows....

Set objXMLDoc = Server.CreateObject("Microsoft.XMLDOM")   
objXMLDoc.async = False    
objXMLDoc.load Server.MapPath("/MovieLibrary/data/videodb.xml")

Dim xmlMovies

Set xmlMovies = objXMLDoc.documentElement.selectNodes("movie")
      
For Each xmlMovie In xmlMovies
    '
    Dim title:title = xmlMovie.selectSingleNode("title").text
    Dim rating_value:rating_value = left(xmlMovie.selectSingleNode("ratings/rating/value").text,3)
    Dim rating_votes:rating_votes = xmlMovie.selectSingleNode("ratings/rating/votes").text
    Dim plot:plot = xmlMovie.selectSingleNode("plot").text
    Dim runtime:runtime = xmlMovie.selectSingleNode("runtime").text
    Dim mpaa_rating:mpaa_rating = xmlMovie.selectSingleNode("mpaa").text
    Dim release_year:release_year = xmlMovie.selectSingleNode("year").text
    Dim id:id = xmlMovie.selectSingleNode("id").text

    Dim genre:genre = xmlMovie.selectSingleNode("genre").text
    
    Dim date_added:date_added = xmlMovie.selectSingleNode("dateadded").text

    Dim actor:actor = xmlMovie.selectSingleNode("actor/name").text
    
    Response.Write Server.HTMLEncode(title) & " "
    Response.Write Server.HTMLEncode(rating_value) & "/10 "
    Response.Write Server.HTMLEncode(rating_votes) & "<br>"
    Response.Write Server.HTMLEncode(plot) & "<br>"
    Response.Write Server.HTMLEncode(runtime) & " Minutes "
    Response.Write Server.HTMLEncode(mpaa_rating) & " "
    Response.Write Server.HTMLEncode(release_year) & " "
    Response.Write Server.HTMLEncode(id) & "<br> "
    Response.Write Server.HTMLEncode(genre) & "<br>"
    Response.Write Server.HTMLEncode(date_added) & "<br>"
    Response.Write Server.HTMLEncode(actor) & "<br><br>"
    
Next

As you can see in the xml file each movie can have several "genre" entries and several "actor" entries. I can get all the entries but I can only get the first "genre" entry and the first "actor" entry. I'm having trouble figuring out how to create a sub-list of the genres listed for each movie so I can push them into my class....and I only want to grab the first 2 or three actors, not 27 as some do.

Obviously I need to create an array for the genre and actor fields but everything I try comes back with something like "this collection doesn't have this method" or nothing at all.

I know my code is messy, this is a test bed I created to make sure I can pull the new format of the file.

Any help will be appreciated. (sorry for the long post)


Solution

  • Use a function to get the text using selectNodes Method

    Function getNodeValue(nodename)
    
        Dim NodeValue : NodeValue = ""
        Dim Nodes
    
        set Nodes = xmlMovie.selectNodes(nodename)
    
        For each Node in Nodes
            If NodeValue = "" Then
                NodeValue =  Node.Text
            Else
                NodeValue = NodeValue & ", " & Node.Text
            End If
        Next
    
        getNodeValue = NodeValue
    
    End Function
    

    This will return a comma delimited string.

    Now you can get all the values like:

    Dim title:title = getNodeValue("title") 
    

    and

    Dim genre:genre = getNodeValue("genre")