iTunes and XSLT

Discussion in 'XML' started by Richard Rudie, Jan 15, 2005.

  1. Have any other Windows iTunes users looked at the XML file iTunes uses as
    its database? (Does iTunes for Mac use an XML file, too?) When I noticed
    that it was XML, I thought it might be useful, or at least instructional, to
    create an XSLT file or few to filter and format the database.

    So I opened it in a text editor, and found a bunch of poorly-designed XML
    structure---or so it seems to me, as I wouldn't be posting a question
    otherwise. The elements are arranged like so:

    <key>27</key>
    <dict>
    <key>Name</key><string>Piano Smasher</string>
    <key>Artist</key><string>Blue Man Group</string>
    <key>Album</key><string>The Complex</string>
    <key>Track Number</key><integer>7</integer>
    <key>Year</key><integer>2003</integer>
    <key>Date Added</key><date>2005-01-15T07:12:26Z</date>
    </dict>

    Is there a means to go about matching those pairs of elements in XSLT? Using
    a <xsl:template match="key"> would leave out the following <dict>, <string>,
    <integer>, <date>, or whatever else.

    To transform a track listing into an HTML table row, for example. How would
    one go about getting the <string> associated with (that follows) the "Name"
    <key>, to put it into the HTML <td>?

    I suspect I'd be better off writing a Perl preprocessor to change the
    <key><xxx> element pairs into <item key="..." data="..."/> or the like
    before attempting to XSLize it.



    Remove the mislead to reply.
     
    Richard Rudie, Jan 15, 2005
    #1
    1. Advertising

  2. Richard Rudie

    Joris Gillis Guest

    Tempore 10:44:00, die Saturday 15 January 2005 AD, hinc in foro {comp.text.xml} scripsit Richard Rudie <>:
    > I opened it in a text editor, and found a bunch of poorly-designed XML
    > structure---or so it seems to me, as I wouldn't be posting a question
    > otherwise. The elements are arranged like so:


    Hi,

    I wouldn't label this XML as poorly-designed (that's my opinion) , but If you prefer the '<item key="..." data="..."/>' structure, you can use this stylesheet:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:eek:utput method="xml" indent="yes"/>

    <xsl:template match="/">
    <xsl:apply-templates select="//key[not(parent::dict)]"/>
    </xsl:template>

    <xsl:template match="key">
    <xsl:apply-templates select="following-sibling::dict[1]"/>
    </xsl:template>

    <xsl:template match="dict">
    <xsl:copy>
    <xsl:attribute name="key">
    <xsl:value-of select="preceding-sibling::key[1]"/>
    </xsl:attribute>
    <xsl:apply-templates select="key" mode="collect"/>
    </xsl:copy>
    </xsl:template>

    <xsl:template match="key" mode="collect">
    <item key="{.}" data="{following-sibling::*[1]}"/>
    </xsl:template>

    </xsl:stylesheet>


    A html track table might be constructed from your original XML with this kind of XSLT:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:eek:utput method="html" indent="yes"/>

    <xsl:template match="/">
    <table>
    <tr><th>Key</th><xsl:apply-templates select="//dict[1]/key" mode="litteral"/></tr>
    <xsl:apply-templates select="//key[not(parent::dict)]"/>
    </table>
    </xsl:template>

    <xsl:template match="key">
    <tr>
    <td><xsl:value-of select="."/></td>
    <xsl:apply-templates select="following-sibling::dict[1]"/>
    </tr>
    </xsl:template>

    <xsl:template match="dict">
    <xsl:apply-templates select="key" mode="collect"/>
    </xsl:template>

    <xsl:template match="key" mode="collect">
    <td><xsl:value-of select="following-sibling::*[1]"/></td>
    </xsl:template>

    <xsl:template match="key" mode="litteral">
    <th><xsl:value-of select="."/></th>
    </xsl:template>

    </xsl:stylesheet>


    The same table might be constructed with the 'cleaned up' XML as input with this stylesheet;
    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:eek:utput method="html" indent="yes"/>

    <xsl:template match="/">
    <table>
    <tr><th>Key</th><xsl:apply-templates select="//dict[1]/item/@key"/></tr>
    <xsl:apply-templates select="//dict"/>
    </table>
    </xsl:template>

    <xsl:template match="dict">
    <tr>
    <td><xsl:value-of select="@key"/></td>
    <xsl:apply-templates select="item"/>
    </tr>
    </xsl:template>

    <xsl:template match="item">
    <td><xsl:value-of select="@data"/></td>
    </xsl:template>

    <xsl:template match="@key">
    <th><xsl:value-of select="."/></th>
    </xsl:template>

    </xsl:stylesheet>

    regards,
    --
    Joris Gillis (http://www.ticalc.org/cgi-bin/acct-view.cgi?userid=38041)
    Deserta faciunt et innovationem appelant
     
    Joris Gillis, Jan 15, 2005
    #2
    1. Advertising

  3. Richard Rudie

    Andy Dingley Guest

    On Sat, 15 Jan 2005 03:44:00 -0600, Richard Rudie
    <> wrote:

    >So I opened it in a text editor, and found a bunch of poorly-designed XML
    >structure-


    Agreed.

    >Is there a means to go about matching those pairs of elements in XSLT?


    Yes. Order is preserved in XSLT, so you can do this. However it's
    somewhat ugly code and nasty to maintain. The key is to use the
    following-sibling:: axis and a predicate of [1] to extract the
    following associated value.

    However this example becomes especially poor when we can't always
    guarantee that they are _pairs_ of values. Personally I don't even try
    - I use a DOM walker with a simple state machine (events of "<key>
    read" and "not-<key> read") to turn it into something more sensible.

    The duplication of "key" as an element name is also ugly, but is a
    problem for maintenance more than code design (use mode= if you're
    doing <template match= ... > )


    I _hate_ XML Schemas cooked up by people who don't really understand
    XML. iTunes and Podcasting in general reeks of this 8-(

    --
    Smert' spamionam
     
    Andy Dingley, Jan 15, 2005
    #3
  4. In article <>,
    Andy Dingley <> wrote:

    > I _hate_ XML Schemas cooked up by people who don't really understand
    > XML.


    What iTunes uses is not a vocabulary designed for the particular use but
    a vocabulary designed for replacing NeXT property lists. The result is
    kind of XML-RPCish.

    --
    Henri Sivonen

    http://iki.fi/hsivonen/
     
    Henri Sivonen, Jan 15, 2005
    #4
  5. Richard Rudie

    Andy Dingley Guest

    On Sun, 16 Jan 2005 00:52:18 +0200, Henri Sivonen <>
    wrote:

    >What iTunes uses is not a vocabulary designed for the particular use but
    >a vocabulary designed for replacing NeXT property lists.


    Even so, you can map name-value pairs onto XML far better than this
    has been done.

    >The result is kind of XML-RPCish.


    Well, you know my feelings on the RSS protocol specs :cool:
     
    Andy Dingley, Jan 16, 2005
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Luis Ferrao

    DataGrid: iTunes-like incremental search

    Luis Ferrao, Jan 10, 2005, in forum: ASP .Net
    Replies:
    4
    Views:
    992
    Luis Ferrao
    Jan 10, 2005
  2. Replies:
    1
    Views:
    950
    Hywel Jenkins
    Apr 17, 2006
  3. Jake Barnes
    Replies:
    0
    Views:
    754
    Jake Barnes
    Jan 25, 2006
  4. Andreas Leitgeb
    Replies:
    2
    Views:
    385
    Andreas Leitgeb
    Jul 10, 2008
  5. Morlence
    Replies:
    0
    Views:
    1,307
    Morlence
    Nov 2, 2009
Loading...

Share This Page