Pergunta

I'm looking to parse some data from the iTunes Library XML file and for that I'd like to have an elegant solution in VBScript to parse the key/value pairs. This is the XML structure:

<plist version="1.0">
    <dict>
        <dict>
            <key>1</key>
            <dict>
                <key>Location</key><string>"file1.mp3"</string>
            </dict>
            <key>2</key>
            <dict>
                <key>Location</key><string>"file2.mp3"</string>
            </dict>
        </dict>
    </dict>
</plist>

I've now listed only two key/value (<key>/<dict>) pairs but of course there are many.

I'd like to parse this into some kind of dictionary object like so:

1 file1.mp3
2 file2.mp3

I can think of some ways to achieve this, like involving the NextSibling() method, but that really seems too far-fetched to me.

So what would be a more official/elegant solution to this problem? Thanks in advance!

Foi útil?

Solução

I would search for the locations and then use family relations to get the key and the file. In code:

  Dim oFS      : Set oFS      = CreateObject("Scripting.FileSystemObject")
  Dim sFSpec   : sFSpec       = goFS.GetAbsolutePathName("..\testdata\xml\so23425116.xml")
  Dim objMSXML : Set objMSXML = CreateObject("Msxml2.DOMDocument")
  objMSXML.setProperty "SelectionLanguage", "XPath"
  objMSXML.async = False
  objMSXML.load sFSpec

  If 0 = objMSXML.parseError Then
     Dim sXPath : sXPath     = "/plist/dict/dict/dict/key[. = ""Location""]"
     Dim ndlFnd : Set ndlFnd = objMSXML.selectNodes(sXPath)
     If 0 = ndlFnd.length Then
        WScript.Echo sXPath, "not found"
     Else
        Dim dicKV : Set dicKV = CreateObject("Scripting.Dictionary")
        Dim ndFnd, ndLoc, ndKey
        For Each ndFnd In ndlFnd
            Set ndLoc = ndFnd.nextSibling
            Set ndKey = ndFnd.parentNode.previousSibling
            WScript.Echo ndKey.text, ndLoc.text
            dicKV(ndKey.text) = ndLoc.text
        Next
        WScript.Echo "------------"
        Dim sKey
        For Each sKey In dicKV
            WScript.Echo sKey, dicKV(sKey)
        Next
     End If
  Else
     WScript.Echo objMSXML.parseError.reason
  End If

sample output (for a variant of your sample .xml):

1 "file1.mp3"
2 "file2.mp3"
290 file://localhost/D:/iTunes/Bob%20Russell%20Sermons/Sermons/1999/01-03%20Good%20News.mp3
------------
1 "file1.mp3"
2 "file2.mp3"
290 file://localhost/D:/iTunes/Bob%20Russell%20Sermons/Sermons/1999/01-03%20Good%20News.mp3

Disclaimers:

  • I don't use iTunes, so I'm not sure that the 2 randomly selected sample .xml I used for testing are really representative.
  • The file specs obviously need some cleaning
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top