I’m writing some code that’ll allow me to control a bands lights 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’m coming at this from a PHP background where turning this XML into an associative array would be easy by that doesn’t appear to be easily doable in VB.Net so I’ve come up with 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 can’t find a way of looping through the section tags and retrieving their properties. My function just sees one section tag and outputs this:
3 => Title: Paramore - Still into you
3 => Section: [
{
"@id": "0",
"@name": "intro",
"@part": "SCENE0"
},
{
"@id": "1",
"@name": "verse",
"@part": "SCENE3"
},
{
"@id": "2",
"@name": "chorus",
"@part": "SCENE2"
},
{
"@id": "3",
"@name": "verse",
"@part": "SCENE4"
},
{
"@id": "4",
"@name": "hold",
"@part": "SCENE7"
}
]
I can’t find anything that exactly matches this issue online, but it must be a fairly common problem. How do I count the number of section tags and (ideally) access the name and part attributes ?
2
Answers
This can be done using XPATH expressions in System.Xml:
Output:
I like to use XElement.
Here is the data showing how to load from URI but using a literal to test with,
And then accessing various parts