iTunes and XSLT

R

Richard Rudie

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.
 
J

Joris Gillis

Tempore 10:44:00 said:
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,
 
A

Andy Dingley

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-(
 
H

Henri Sivonen

Andy Dingley said:
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.
 
A

Andy Dingley

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:
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,241
Members
46,831
Latest member
RusselWill

Latest Threads

Top