Created
January 20, 2010 15:35
-
-
Save mro/281919 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
default namespace = "http://filmfestapp.com/schema/festival/v1" | |
namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0" | |
start = | |
## Flat Xml Schema for http://filmfestapp.com festival catalogues. | |
## | |
## This is a http://relaxng.org/ compact schema, to convert to RelaxNG regular or w3c-xsd use | |
## http://www.thaiopensource.com/relaxng/trang.html | |
## | |
## To validate use e.g. http://xmlsoft.org/xmllint.html | |
## $ xmllint --relaxng filmfest.flatv1.rng document.xml | |
element festival { | |
element creatorUrl { | |
xsd:anyURI { minLength = "1" } | |
}, | |
geo?, | |
element homepage { | |
xsd:anyURI { minLength = "1" } | |
}, | |
element iconUrl { | |
xsd:anyURI { minLength = "1" } | |
}, | |
element section { | |
element movie { | |
element actor { | |
xsd:string { pattern = "\S(.*\S)?" } | |
}*, | |
element contact { | |
xsd:string { pattern = "\S(.*\S)?" } | |
}?, | |
element country { | |
xsd:string { | |
## subset of "ISO country code" | |
pattern = "[A-Z]{3}" | |
} | |
}+, | |
element synopsis { text }, | |
element director { | |
xsd:string { pattern = "\S(.*\S)?" } | |
}+, | |
element distributor { | |
xsd:string { pattern = "\S(.*\S)?" } | |
}?, | |
element festivalUrl { | |
xsd:anyURI { minLength = "0" } | |
}, | |
element footage { | |
xsd:string { pattern = "\S(.*\S)?" } | |
}?, | |
element iconUrl { | |
xsd:anyURI { minLength = "1" } | |
}, | |
element imdbUrl { | |
xsd:anyURI { minLength = "1" } | |
}, | |
element language { | |
xsd:string { | |
## A ISO 2-letter language code | |
pattern = "[a-z]{2}" | |
} | |
}*, | |
element otitle { | |
xsd:string { pattern = "\S(.*\S)?" } | |
}?, | |
element producer { | |
xsd:string { pattern = "\S(.*\S)?" } | |
}*, | |
element screening { | |
element minutes { | |
xsd:integer { minInclusive = "1" maxInclusive = "1440" } | |
}, | |
element dtstart { | |
xsd:dateTime { | |
pattern = | |
"[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z" | |
} | |
}, | |
uuid, | |
element venueref { | |
attribute idref { xsd:NCName } | |
} | |
}*, | |
element scriptwriter { | |
xsd:string { pattern = "\S(.*\S)?" } | |
}*, | |
element subtitle { | |
xsd:string { pattern = "\S(.*\S)?" } | |
}?, | |
title, | |
element trailerUrl { | |
xsd:anyURI { | |
## youtube only | |
pattern = | |
"http.+\.youtube\.com/(v/|watch\?v=)([A-Za-z0-9._%\-]+)" | |
} | |
}?, | |
element year { | |
xsd:integer { minInclusive = "1900" maxInclusive = "2100" } | |
} | |
}+, | |
title | |
}+, | |
element shortName { | |
xsd:string { pattern = "\S(.*\S)?" } | |
}, | |
title, | |
uuid, | |
element venue { | |
attribute id { xsd:NCName }, | |
element address { | |
element city { | |
xsd:string { pattern = "\S(.*\S)?" } | |
}, | |
element country { | |
xsd:string { pattern = "\S(.*\S)?" } | |
}, | |
element street { | |
xsd:string { pattern = "\S(.*\S)?" } | |
}, | |
element zip { | |
xsd:string { pattern = "\S(.*\S)?" } | |
} | |
}, | |
geo, | |
element phone { | |
xsd:string { pattern = "\S(.*\S)?" } | |
}, | |
title | |
}+ | |
} | |
geo = | |
element geo { | |
xsd:string { | |
## A geo location | |
pattern = "(-?[0-9]+\.[0-9]+)[,;](-?[0-9]+\.[0-9]+)" | |
} | |
} | |
uuid = | |
element uuid { | |
xsd:string { | |
## A UUID | |
pattern = | |
"[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}" | |
} | |
} | |
title = | |
element title { | |
xsd:string { pattern = "\S(.*\S)?" } | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0"?> | |
<xsl:stylesheet version="1.0" | |
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:f="http://filmfestapp.com/schema/festival/v1" | |
exclude-result-prefixes="f"> | |
<xsl:output method="xml" /> | |
<xsl:output indent="yes" /> | |
<xsl:template match="/"> | |
<xsl:text disable-output-escaping="yes"><![CDATA[<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">]]></xsl:text> | |
<plist version="1.0"> | |
<xsl:for-each select="f:festival"> | |
<dict> | |
<key>schemaversion</key> | |
<integer>1</integer> | |
<xsl:for-each | |
select="f:geo | f:creatorUrl | f:iconUrl | f:homepage | f:uuid | f:shortName | f:title"> | |
<key><xsl:value-of select="name(.)" /></key> | |
<string><xsl:value-of select="text()" /></string> | |
</xsl:for-each> | |
<key>sections</key> | |
<array> | |
<xsl:for-each select="f:section"> | |
<dict> | |
<key>title</key> | |
<string><xsl:value-of select="f:title" /></string> | |
<key>movies</key> | |
<array> | |
<xsl:for-each select="f:movie"> | |
<dict> | |
<xsl:for-each select="f:iconUrl | f:festivalUrl | f:trailerUrl | f:imdbUrl | f:title | f:footage | f:contact | f:distributor"> | |
<key><xsl:value-of select="name(.)" /></key> | |
<string><xsl:value-of select="text()" /></string> | |
</xsl:for-each> | |
<xsl:for-each select="f:synopsis"> | |
<key>description</key> | |
<string><xsl:value-of select="text()" /></string> | |
</xsl:for-each> | |
<xsl:for-each select="f:year"> | |
<key><xsl:value-of select="name(.)" /></key> | |
<integer><xsl:value-of select="text()" /></integer> | |
</xsl:for-each> | |
<key>directors</key> | |
<array> | |
<xsl:for-each select="f:director"> | |
<string><xsl:value-of select="text()" /></string> | |
</xsl:for-each> | |
</array> | |
<key>producers</key> | |
<array> | |
<xsl:for-each select="f:producer"> | |
<string><xsl:value-of select="text()" /></string> | |
</xsl:for-each> | |
</array> | |
<key>actors</key> | |
<array> | |
<xsl:for-each select="f:actor"> | |
<string><xsl:value-of select="text()" /></string> | |
</xsl:for-each> | |
</array> | |
<key>scriptwriters</key> | |
<array> | |
<xsl:for-each select="f:scriptwriter"> | |
<string><xsl:value-of select="text()" /></string> | |
</xsl:for-each> | |
</array> | |
<key>countries</key> | |
<array> | |
<xsl:for-each select="f:country"> | |
<string><xsl:value-of select="text()" /></string> | |
</xsl:for-each> | |
</array> | |
<key>languages</key> | |
<array> | |
<xsl:for-each select="f:language"> | |
<string><xsl:value-of select="text()" /></string> | |
</xsl:for-each> | |
</array> | |
<key>subtitles</key> | |
<array> | |
<xsl:for-each select="f:subtitle"> | |
<string><xsl:value-of select="text()" /></string> | |
</xsl:for-each> | |
</array> | |
<key>screenings</key> | |
<array> | |
<xsl:for-each select="f:screening"> | |
<dict> | |
<key>duration</key> | |
<real><xsl:value-of select="f:minutes * 60" /></real> | |
<key>start</key> | |
<date><xsl:value-of select="f:dtstart" /></date> | |
<key>uuid</key> | |
<string><xsl:value-of select="f:uuid" /></string> | |
<key>venue</key> | |
<string><xsl:value-of select="f:venueref/@idref" /></string> | |
</dict> | |
</xsl:for-each> | |
</array> | |
</dict> | |
</xsl:for-each> | |
</array> | |
</dict> | |
</xsl:for-each> | |
</array> | |
<key>venues</key> | |
<dict> | |
<xsl:for-each select="f:venue"> | |
<key><xsl:value-of select="@id" /></key> | |
<dict> | |
<key>id</key> | |
<string><xsl:value-of select="@id" /></string> | |
<key>title</key> | |
<string><xsl:value-of select="f:title" /></string> | |
<key>phone</key> | |
<string><xsl:value-of select="f:phone" /></string> | |
<key>geo</key> | |
<string><xsl:value-of select="f:geo" /></string> | |
<xsl:for-each select="f:address"> | |
<key>address</key> | |
<dict> | |
<key>street</key> | |
<string><xsl:value-of select="f:street" /></string> | |
<key>city</key> | |
<string><xsl:value-of select="f:city" /></string> | |
<key>zip</key> | |
<string><xsl:value-of select="f:zip" /></string> | |
<key>country</key> | |
<string><xsl:value-of select="f:country" /></string> | |
</dict> | |
</xsl:for-each> | |
</dict> | |
</xsl:for-each> | |
</dict> | |
</dict> | |
</xsl:for-each> | |
</plist> | |
</xsl:template> | |
</xsl:stylesheet> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0"?> | |
<xsl:stylesheet version="1.0" | |
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" | |
xmlns='http://filmfestapp.com/schema/festival/v1'> | |
<!-- | |
<xsl:output method="xml" /> | |
<xsl:output indent="yes" /> | |
--> | |
<!-- unwrap one level, rename node add id attribute --> | |
<xsl:template match="key[text() = 'venues']"> | |
<xsl:for-each select="following-sibling::dict[1]/key"> | |
<venue> | |
<xsl:attribute name="id"> | |
<xsl:value-of select="text()" /> | |
</xsl:attribute> | |
<xsl:apply-templates select="following-sibling::*[1]" /> | |
</venue> | |
</xsl:for-each> | |
</xsl:template> | |
<!-- unwrap one level and rename node --> | |
<xsl:template match="key[text() = 'sections' or text() = 'movies' or text() = 'directors' or text() = 'actors' or text() = 'producers' or text() = 'scriptwriters' or text() = 'languages' or text() = 'subtitles' or text() = 'screenings']"> | |
<xsl:apply-templates select="following-sibling::*[1]"> | |
<xsl:with-param name="key"> | |
<xsl:value-of select="substring(text(),0,string-length(text()))" /> | |
</xsl:with-param> | |
</xsl:apply-templates> | |
</xsl:template> | |
<!-- unwrap one level and rename node --> | |
<xsl:template match="key[text() = 'countries']"> | |
<xsl:apply-templates select="following-sibling::*[1]"> | |
<xsl:with-param name="key">country</xsl:with-param> | |
</xsl:apply-templates> | |
</xsl:template> | |
<!-- drop --> | |
<xsl:template match="key[text() = 'schemaversion' or text() = 'section' or text() = 'sectionId']" /> | |
<!-- rename node --> | |
<xsl:template match="key[text() = 'description']"> | |
<synopsis><xsl:value-of select="following-sibling::*[1]/text()" /></synopsis> | |
</xsl:template> | |
<!-- rename node --> | |
<xsl:template match="key[text() = 'start']"> | |
<dtstart><xsl:value-of select="following-sibling::*[1]/text()" /></dtstart> | |
</xsl:template> | |
<!-- rename node --> | |
<xsl:template match="key[text() = 'duration']"> | |
<minutes><xsl:value-of select="following-sibling::*[1]/text() div 60" /></minutes> | |
</xsl:template> | |
<!-- refill into idref attribute --> | |
<xsl:template match="key[text() = 'venue']"> | |
<venueref idref="{following-sibling::*[1]/text()}" /> | |
</xsl:template> | |
<!-- Start converting - generic pattern --> | |
<xsl:template match="/"> | |
<festival> | |
<!-- <xsl:for-each select="plist/dict/dict/key"> | |
<venue> | |
<xsl:attribute name="id"> | |
<xsl:value-of select="text()" /> | |
</xsl:attribute> | |
<xsl:apply-templates select="following-sibling::*[1]" /> | |
</venue> | |
</xsl:for-each> | |
<xsl:for-each select="plist/dict/array/dict"> | |
<section> | |
<xsl:apply-templates select="key" /> | |
</section> | |
</xsl:for-each> | |
--> <xsl:apply-templates select="plist/dict/key" /> | |
</festival> | |
</xsl:template> | |
<!-- turn <key>foo</key><value>bar</value> into <foo>bar</foo> --> | |
<xsl:template match="key"> | |
<xsl:element name="{.}"> | |
<xsl:apply-templates select="following-sibling::*[1]"> | |
<xsl:with-param name="key"> | |
<xsl:value-of select="text()" /> | |
</xsl:with-param> | |
</xsl:apply-templates> | |
</xsl:element> | |
</xsl:template> | |
<xsl:template match="dict"> | |
<xsl:apply-templates select="key[text() != 'id']" /> | |
</xsl:template> | |
<xsl:template match="array"> | |
<xsl:param name="key"> | |
item | |
</xsl:param> | |
<xsl:for-each select="*"> | |
<xsl:element name="{$key}"> | |
<xsl:apply-templates select="." /> | |
</xsl:element> | |
</xsl:for-each> | |
</xsl:template> | |
</xsl:stylesheet> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment