1

I have a large xml file that I want to parse and store as objects. At the moment I am just trying to parse all the information, and then after I will try store it in objects. So far i am only able to parse strings from the xml file, but I would like to be able to parse integers as well and I am not sure how I would do this in the same loop as that is where I will store them as objects.

Below is my code:

FileInputStream file = new FileInputStream(new File("itunes2.xml"));
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();

    Document document = builder.parse(file);

    Element root = document.getDocumentElement();
    System.out.println(root.getNodeName());
    System.out.println("============================");

    XPath xPath = XPathFactory.newInstance().newXPath();
    NodeList nList = (NodeList) xPath.evaluate("/plist/dict/dict/dict/key[text()='Name']/following::string[1]", root, XPathConstants.NODESET);
    for (int i = 0; i < nList.getLength(); ++i) {
        Element e = (Element) nList.item(i);
        String value = e.getFirstChild().getNodeValue();
        System.out.println("Name: " + value);
    }

And my xml file:

<plist version="1.0">
<dict>
<key>Major Version</key><integer>1</integer>
<key>Minor Version</key><integer>1</integer>
<key>Application Version</key><string>10.1</string>
<key>Features</key><integer>5</integer>
<key>Show Content Ratings</key><true/>
<key>Music Folder</key><string>file://localhost//Thomts/Holly/data/My%20Music/iTunes/iTunes%20Music/</string>
<key>Library Persistent ID</key><string>29E12A03204E0721</string>
<key>Tracks</key>
<dict>
    <key>324</key>
    <dict>
        <key>Track ID</key><integer>324</integer>
        <key>Name</key><string>Talk Dirty To Me</string>
        <key>Artist</key><string>Poison</string>
        <key>Composer</key><string>Poison</string>
        <key>Album</key><string>The Best Of Poison: 20 Years Of Rock</string>
        <key>Genre</key><string>Metal</string>
        <key>Kind</key><string>AAC audio file</string>
        <key>Size</key><integer>3698203</integer>
        <key>Total Time</key><integer>224866</integer>
        <key>Disc Number</key><integer>1</integer>
        <key>Disc Count</key><integer>1</integer>
        <key>Track Number</key><integer>1</integer>
        <key>Track Count</key><integer>18</integer>
        <key>Year</key><integer>1986</integer>
        <key>Date Modified</key><date>2008-08-07T15:16:57Z</date>
        <key>Date Added</key><date>2008-08-07T15:17:17Z</date>
        <key>Bit Rate</key><integer>128</integer>
        <key>Sample Rate</key><integer>44100</integer>
        <key>Play Count</key><integer>6</integer>
        <key>Play Date</key><integer>3378486192</integer>
        <key>Play Date UTC</key><date>2011-01-22T03:23:12Z</date>
        <key>Compilation</key><true/>
        <key>Sort Album</key><string>Best Of Poison: 20 Years Of Rock</string>
        <key>Persistent ID</key><string>29E12A03204E0873</string>
        <key>Track Type</key><string>File</string>
        <key>Location</key><string>file://localhost//Thomts/Holly/data/My%20Music/iTunes/iTunes%20Music/Compilations/The%20Best%20Of%20Poison_%2020%20Years%20Of%20Rock/01%20Talk%20Dirty%20To%20Me.m4a</string>
        <key>File Folder Count</key><integer>4</integer>
        <key>Library Folder Count</key><integer>1</integer>
    </dict>
    <key>326</key>
    <dict>
        <key>Track ID</key><integer>326</integer>
        <key>Name</key><string>I Want Action [Single Version]</string>
        <key>Artist</key><string>Poison</string>
        <key>Composer</key><string>Poison</string>
        <key>Album</key><string>The Best Of Poison: 20 Years Of Rock</string>
        <key>Genre</key><string>Metal</string>
        <key>Kind</key><string>AAC audio file</string>
        <key>Size</key><integer>3070259</integer>
        <key>Total Time</key><integer>185893</integer>
        <key>Disc Number</key><integer>1</integer>
        <key>Disc Count</key><integer>1</integer>
        <key>Track Number</key><integer>2</integer>
        <key>Track Count</key><integer>18</integer>
        <key>Year</key><integer>1986</integer>
        <key>Date Modified</key><date>2008-08-07T15:17:12Z</date>
        <key>Date Added</key><date>2008-08-07T15:17:32Z</date>
        <key>Bit Rate</key><integer>128</integer>
        <key>Sample Rate</key><integer>44100</integer>
        <key>Play Count</key><integer>3</integer>
        <key>Play Date</key><integer>3367665479</integer>
        <key>Play Date UTC</key><date>2010-09-18T21:37:59Z</date>
        <key>Compilation</key><true/>
        <key>Sort Album</key><string>Best Of Poison: 20 Years Of Rock</string>
        <key>Persistent ID</key><string>29E12A03204E087A</string>
        <key>Track Type</key><string>File</string>
        <key>Location</key><string>file://localhost//Thomts/Holly/data/My%20Music/iTunes/iTunes%20Music/Compilations/The%20Best%20Of%20Poison_%2020%20Years%20Of%20Rock/02%20I%20Want%20Action%20%5BSingle%20Version%5D.m4a</string>
        <key>File Folder Count</key><integer>4</integer>
        <key>Library Folder Count</key><integer>1</integer>
    </dict>
 </dict>
</dict>

My Song.java:

public class Song {

private int id, size, totalTime, discnumber, disccount, trackNumber, trackCount, year;
private String name, artist, composer, album, genre, kind;
public Song(int id, int size, int totalTime, int discnumber, int disccount,
        int trackNumber, int trackCount, int year, String name,
        String artist, String composer, String album, String genre,
        String kind) {
    super();
    this.id = id;
    this.size = size;
    this.totalTime = totalTime;
    this.discnumber = discnumber;
    this.disccount = disccount;
    this.trackNumber = trackNumber;
    this.trackCount = trackCount;
    this.year = year;
    this.name = name;
    this.artist = artist;
    this.composer = composer;
    this.album = album;
    this.genre = genre;
    this.kind = kind;
}        

The expression I am using at the moment (/plist/dict/dict/dict/key[text()='Name']/following::string[1]) works, but I would also like to use another expression for integers, and then store these all in objects in the same loop. I have tried but yet to have success. Could anyone help me with this please?

1 Answer 1

1

The idea is to select the element that contain all information you need to populate each Song object i.e the inner most <dict> element. Iterate through the <dict>, and in every iteration use relative XPath expression to get the detailed information, for example :

.....
.....
NodeList nList = (NodeList)xPath.evaluate("/plist/dict/dict/dict", root, XPathConstants.NODESET);
for (int i = 0; i < nList.getLength(); ++i) {
    Element dict = (Element)nList.item(i);

    //get current TRACK ID and print
    Double trackId = (Double)xPath.evaluate("key[.='Track ID']/following-sibling::integer[1]", dict, XPathConstants.NUMBER);
    System.out.println("Track ID: " + trackId.toString());

    //get current NAME and print
    String name = (String)xPath.evaluate("key[.='Name']/following-sibling::string[1]", dict, XPathConstants.STRING);
    System.out.println("Name: " + name);

    //get further information and process as needed
    .....
    .....
}
Sign up to request clarification or add additional context in comments.

1 Comment

This is a great answer. Thanks, it helps me a lot!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.