I'm writing some code that'll allow me to control a bands light by sending a MIDI note to a VB.net program. The setlist and structure of each song is defined in an XML file as well as the lighting sequence to use in each section of the song (verse, chorus, outro etc.). The XML file looks like this:
<?xml version="1.0" standalone="yes"?>
<setlist>
<song>
<title>Blink 182 - All the Small Things</title>
<section id = "0" name = "intro" part = "SCENE0"></section>
<section id = "1" name = "verse" part = "SCENE1"></section>
<section id = "2" name = "chorus" part = "SCENE2"></section>
<section id = "3" name = "verse" part = "SCENE3"></section>
<section id = "4" name = "solo" part = "SCENE4"></section>
<section id = "5" name = "chorus" part = "SCENE5"></section>
<section id = "6" name = "outro" part = "SCENE6"></section>
<section id = "7" name = "hold" part = "SCENE7"></section>
</song>
<song>
<title>Green Day - Holiday</title>
<section id = "0" name = "intro" part = "SCENE0"></section>
<section id = "1" name = "verse" part = "SCENE3"></section>
<section id = "2" name = "chorus" part = "SCENE2"></section>
<section id = "3" name = "verse" part = "SCENE4"></section>
<section id = "4" name = "solo" part = "SCENE5"></section>
<section id = "5" name = "outro" part = "SCENE6"></section>
<section id = "6" name = "hold" part = "SCENE7"></section>
</song>
<song>
<title>Paramore - Still into you</title>
<section id = "0" name = "intro" part = "SCENE0"></section>
<section id = "1" name = "verse" part = "SCENE3"></section>
<section id = "2" name = "chorus" part = "SCENE2"></section>
<section id = "3" name = "verse" part = "SCENE4"></section>
<section id = "4" name = "hold" part = "SCENE7"></section>
</song>
</setlist>
I tried the following code which converts the XML file into a JSON array and then loops through it.
What I'm currently trying to get is the number of songs and the number of sections in each, e.g., song 1 8 sections, song 2 7 sections and song 3 5 sections. These will be stored in an array for later use.
This is my VB function:
Private Sub readSetList(setListFile As String)
' Read setlist data
Dim setlist As New XmlDocument()
setlist.Load(setListFile)
' Convert to JSON
Dim JsonString As String = JsonConvert.SerializeXmlNode(setlist)
' Convert to an array
Dim JsonArray As JObject = JObject.Parse(JsonString)
Dim songCount As Integer = 0
Dim sectionCount As Integer = 0
For Each item As JProperty In JsonArray.Item("setlist")
Dim itemObjects As JToken = item.Value
For Each i As JObject In itemObjects
For Each p In i
' If the key is 'title' then this is a new song so increment the song counter
If p.Key.ToString = "title" Then
songCount += 1
Debug.Print(songCount & " => Title: " & p.Value.ToString)
End If
If p.Key.ToString = "section" Then
sectionCount += 1
Debug.Print(sectionCount & " => Section: " & p.Value.ToString)
End If
Next
Next
Next
End Sub
Whilst this successfully counts the number of songs, I am looking for a way of looping through the section tags and retrieving their properties. following function outputs JSON objects with one section tag:
3 => Title: Paramore - Still into you
3 => Section: [
{
"@id": "0",
"@name": "intro",
"@part": "SCENE0"
},
{
"@id": "1",
"@name": "verse",
"@part": "SCENE3"
},
//...
How do I count the number of section tags and (ideally) access the name and part attributes?
This can be done using XPATH expressions in System.Xml:
Imports System.Xml
Module Program
Sub Main(args As String())
Dim setList = New XmlDocument
setList.Load("songlist.xml")
Dim songs = setList.DocumentElement.SelectNodes("/setlist/song")
Console.WriteLine($"{songs.Count} song(s)")
For Each song As XmlNode In songs
Dim title As String = song.SelectSingleNode("title").FirstChild.Value 'retrieve contents of title node
Dim sections = song.SelectNodes("section")
Dim fifthSectionPart = sections(4).SelectSingleNode("@part").Value 'syntax to retrieve an attribute
Console.WriteLine($"'{title}' has {sections.Count} sections, the fifth section's part is called '{fifthSectionPart}'")
Next song
End Sub
End Module
Output:
3 song(s)
'Blink 182 - All the Small Things' has 8 sections, the fifth section's part is called 'SCENE4'
'Green Day - Holiday' has 7 sections, the fifth section's part is called 'SCENE5'
'Paramore - Still into you' has 5 sections, the fifth section's part is called 'SCENE7'