Monday, January 04, 2010

Schema of iTunes podcast feed

In 2006, in order to aggregate my favourite podcasts and share them with other iPod owners, I did a podcast aggregation service named myTunes.

I chose JAXB to map XML documents to Java objects and vice versa, so I need a schema or DTD file of iTunes podcast feed. Unfortunately I couldn't find one. I had to generate one myself.

I got an example feed from Apple. I removed a few elements that I think of no use at the moment and generated its schema.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" elementFormDefault="qualified">
    <xs:complexType name="channelType">
        <xs:sequence>
            <xs:element ref="title"/>
            <xs:element ref="link"/>
            <xs:element ref="language"/>
            <xs:element ref="description"/>
            <xs:element ref="pubDate"/>
            <xs:element name="image" type="imageType"/>
            <xs:element ref="copyright"/>
            <xs:element ref="subtitle"/>
            <xs:element ref="summary"/>
            <xs:element name="item" type="itemType" maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
    <xs:element name="copyright">
        <xs:simpleType>
            <xs:restriction base="xs:string">
            </xs:restriction>
        </xs:simpleType>
    </xs:element>
        <xs:element name="subtitle">
        <xs:simpleType>
            <xs:restriction base="xs:string">
            </xs:restriction>
        </xs:simpleType>
    </xs:element>
        <xs:element name="summary">
        <xs:simpleType>
            <xs:restriction base="xs:string">
            </xs:restriction>
        </xs:simpleType>
    </xs:element>
    <xs:element name="description">
        <xs:simpleType>
            <xs:restriction base="xs:string">
            </xs:restriction>
        </xs:simpleType>
    </xs:element>
    <xs:complexType name="enclosureType">
        <xs:attribute name="url" use="required">
            <xs:simpleType>
                <xs:restriction base="xs:anyURI">
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
        <xs:attribute name="length" use="required">
            <xs:simpleType>
                <xs:restriction base="xs:int">
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
        <xs:attribute name="type" use="required">
            <xs:simpleType>
                <xs:restriction base="xs:string">
                </xs:restriction>
            </xs:simpleType>
        </xs:attribute>
    </xs:complexType>
    <xs:element name="guid">
        <xs:simpleType>
            <xs:restriction base="xs:anyURI">
            </xs:restriction>
        </xs:simpleType>
    </xs:element>
    <xs:complexType name="imageType">
        <xs:sequence>
            <xs:element ref="url"/>
            <xs:element ref="title"/>
            <xs:element ref="link"/>
        </xs:sequence>
    </xs:complexType>
    <xs:complexType name="itemType">
        <xs:sequence>
            <xs:element ref="title"/>
            <xs:element ref="link"/>
            <xs:element ref="description"/>
            <xs:element ref="subtitle"/>
            <xs:element ref="summary"/>
            <xs:element name="enclosure" type="enclosureType"/>
            <xs:element ref="guid"/>
            <xs:element ref="pubDate"/>
            <xs:element ref="duration"/>
        </xs:sequence>
    </xs:complexType>
    <xs:element name="language">
        <xs:simpleType>
            <xs:restriction base="xs:string">
            </xs:restriction>
        </xs:simpleType>
    </xs:element>
    <xs:element name="link">
        <xs:simpleType>
            <xs:restriction base="xs:anyURI">
            </xs:restriction>
        </xs:simpleType>
    </xs:element>
    <xs:element name="pubDate">
        <xs:simpleType>
            <xs:restriction base="xs:string">
            </xs:restriction>
        </xs:simpleType>
    </xs:element>
    <xs:element name="duration">
        <xs:simpleType>
            <xs:restriction base="xs:string">
            </xs:restriction>
        </xs:simpleType>
    </xs:element>
    <xs:element name="rss">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="channel" type="channelType"/>
            </xs:sequence>
            <xs:attribute name="version" use="required">
                <xs:simpleType>
                    <xs:restriction base="xs:decimal">
                        <xs:enumeration value="2.0"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
        </xs:complexType>
    </xs:element>
    <xs:element name="title">
        <xs:simpleType>
            <xs:restriction base="xs:string">
            </xs:restriction>
        </xs:simpleType>
    </xs:element>
    <xs:element name="url">
        <xs:simpleType>
            <xs:restriction base="xs:anyURI">
            </xs:restriction>
        </xs:simpleType>
    </xs:element>
</xs:schema>

Then I created Java classes (ObjectFactory.java, Rss.java, ChannelType.java, ImageType.java, ItemType.java and EnclosureType.java) using xjc. Now we're ready to output iTunes compatible podcast feed.

I had closed myTunes before I moved to Melbourne in 2008. In less than 2 years, myTunes collected several hundreds of user agent (it only collects user agent, nothing else). I think it'll be a good idea to publish them one day.

No comments:

Post a Comment