Search code examples
xmlparsingc#-4.0xmlreaderxspf

C# Parsing XML (.xspf file)


i have a playlist(s) that i need to parse and i need to do stuff like set them in list box etc. here is the .xspf

<?xml version="1.0" encoding="UTF-8"?>
<playlist xmlns="http://xspf.org/ns/0/" xmlns:vlc="http://www.videolan.org/vlc/playlist/ns/0/" version="1">
    <title>Playlist</title>
    <trackList>
        <track>
            <location>file:///E:/Downloads/video1.mp4</location>
            <duration>681493</duration>
            <extension application="http://www.videolan.org/vlc/playlist/0">
                <vlc:id>0</vlc:id>
            </extension>
        </track>
        <track>
            <location>file:///E:/Downloads/video2.mp4</location>
            <duration>614585</duration>
            <extension application="http://www.videolan.org/vlc/playlist/0">
                <vlc:id>1</vlc:id>
            </extension>
        </track>
        <track>
            <location>file:///E:/Downloads/video3.mp4</location>
            <duration>220629</duration>
            <extension application="http://www.videolan.org/vlc/playlist/0">
                <vlc:id>2</vlc:id>
            </extension>
        </track>        
    </trackList>
    <extension application="http://www.videolan.org/vlc/playlist/0">
        <vlc:node title="oh.xspf">
        <vlc:node title="B">
            <vlc:item tid="0"/>
            <vlc:item tid="1"/>         
        </vlc:node>
        <vlc:node title="Solo">
            <vlc:item tid="2"/>         
        </vlc:node>
    </extension>
</playlist>

And here is the C# code that works but i get problems since i use "node.ChildNode.Item(1).InnerText" some files have more metadata than just "location" "duration". but i cant seem to get to work using the element name to get the info i want

 private void button1_Click(object sender, EventArgs e)
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load("1.xspf");
            XmlNodeList nodeList = xmlDoc.GetElementsByTagName("track");
            string proID = "", proName = "";
            foreach (XmlNode node in nodeList)
            {
                    proID = node.ChildNodes.Item(1).InnerText;//ChildNodes.Item(1).InnerText;
                    //proName = node.SelectSingleNode("duration").InnerText;
                    listBox1.Items.Add(proID);


            }       
        }

Solution

  • Use xml linq like below. Add using System.Xml.Linq; to top of module

            const string FILENAME = @"c:\temp\test.xml";
            XDocument doc = XDocument.Load(FILENAME);
            XNamespace ns = ((XElement)doc.FirstNode).Name.Namespace;
            var data = doc.Descendants(ns + "track").Select(x => new object[] {
                (string)x.Element(ns + "location"),
                (int)x.Element(ns + "duration"),
                int.Parse(x.Element(ns + "extension").Value),
                (string)x.Element(ns + "extension").Attribute("application")
            }).ToList();
    
            foreach (object prodID in data)
            {
                listBox1.Items.Add(prodID);
            }