﻿<?xml version="1.0"?>
<!--
	© Jon Hanna 2002
-->
<!--
	I really couldn't care less what anyone does with this, but claiming
	that they wrote it would be just sad and in asserting my right
	of intellectual property I assert my right to publicly ridicule
	anyone who does.
-->
<!--
	The basic idea of this is to perform an operation on RDF triplets
	with Qualified Dublin Core predicates that applying rule rdfs6
	at http://www.w3.org/TR/rdf-mt/#rdfs_entail.
	
	Example:
	
	http://purl.org/dc/terms/ includes the triplet:
	
<http://purl.org/dc/terms/created> <http://www.w3.org/2000/01/rdf-schema#subPropertyOf> <http://purl.org/dc/elements/1.1/date>

	Therefore whenever we encounter a triplet like:

<xxx> <http://purl.org/dc/terms/created> <yyy>

	We can assume the triplet:

<xxx> <http://purl.org/dc/elements/1.1/date> <yyy>

	This XSL attempts to make such an implication explicit by producing an
	output RDF/XML document that is identical to the input RDF/XML document
	except that it will add elements to apply the rule above.
	
	So far it only does so for Dublin Core elements that have been serialised
	to XML as elements, so there are valid ways of expressing an appropriate
	triplet that won't be used in this way.
	
	The XSL attempts to avoid unnecessary duplication.
	
	Comments welcome to mailto:jon@spin.ie
-->
<xsl:stylesheet
	version="1.0"
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:dcq="http://purl.org/dc/terms/"
	exclude-result-prefixes="dc dcq">
	<xsl:output
		method="xml"
		version="1.0"
		encoding="UTF-8"
		omit-xml-declaration="no"
		standalone="yes"
		indent="yes"
		media-type="application/rdf+xml"/>
	<xsl:template match="/">
		<xsl:apply-templates select="*"/>
	</xsl:template>
	<xsl:template match="dcq:created[not(ancestor::dc:*)]">
		<xsl:copy>
			<xsl:apply-templates select="*|@*|text()"/>
		</xsl:copy>
		<dc:date>
			<xsl:apply-templates select="*|@*|text()"/>
		</dc:date>
	</xsl:template>
	<xsl:template match="dcq:created|dcq:issued|dcq:modified|dcq:valid|dcq:available">
		<xsl:copy>
			<xsl:apply-templates select="*|@*|text()"/>
		</xsl:copy>
		<xsl:if test="not(ancestor::dc:*
		|../dc:date[string()=string(current())]
		|preceding-sibling::dcq:created[string()=string(current())]
		|preceding-sibling::dcq:issued[string()=string(current())]
		|preceding-sibling::dcq:modified[string()=string(current())]
		|preceding-sibling::dcq:valid[string()=string(current())]
		|preceding-sibling::dcq:available[string()=string(current())])">
			<dc:date>
				<xsl:apply-templates select="*|@*|text()"/>
			</dc:date>
		</xsl:if>
	</xsl:template>
	<xsl:template match="dcq:isPartOf|dcq:hasPart|dcq:isVersionOf|dcq:hasVersion|dcq:isFormatOf|dcq:hasFormat|dcq:references|dcq:isReferencedBy|dcq:requires|dcq:isRequiredBy|dcq:replaces|dcq:isReplacedBy|dcq:conformsTo">
		<xsl:copy>
			<xsl:apply-templates select="*|@*|text()"/>
		</xsl:copy>
		<xsl:if test="not(ancestor::dc:*
		|../dc:relation[string()=string(current())]
		|preceding-sibling::dcq:isPartOf[string()=string(current())]
		|preceding-sibling::dcq:hasPart[string()=string(current())]
		|preceding-sibling::dcq:isVersionOf[string()=string(current())]
		|preceding-sibling::dcq:hasVersion[string()=string(current())]
		|preceding-sibling::dcq:isFormatOf[string()=string(current())]
		|preceding-sibling::dcq:hasFormat[string()=string(current())]
		|preceding-sibling::dcq:references[string()=string(current())]
		|preceding-sibling::dcq:isReferencedBy[string()=string(current())]
		|preceding-sibling::dcq:requires[string()=string(current())]
		|preceding-sibling::dcq:isRequiredBy[string()=string(current())]
		|preceding-sibling::dcq:replaces[string()=string(current())]
		|preceding-sibling::dcq:isReplacedBy[string()=string(current())]
		|preceding-sibling::dcq:conformsTo[string()=string(current())])">
			<dc:relation>
				<xsl:apply-templates select="*|@*|text()"/>
			</dc:relation>
		</xsl:if>
	</xsl:template>
	<xsl:template match="dcq:abstract|dcq:node|dcq:tableOfContents|dcq:release">
		<xsl:copy>
			<xsl:apply-templates select="*|@*|text()"/>
		</xsl:copy>
		<xsl:if test="not(ancestor::dc:*
		|../dc:description[string()=string(current())]
		|preceding-sibling::dcq:abstract[string()=string(current())]
		|preceding-sibling::dcq:node[string()=string(current())]
		|preceding-sibling::dcq:tableOfContents[string()=string(current())]
		|preceding-sibling::dcq:release[string()=string(current())])">
			<dc:description>
				<xsl:apply-templates select="*|@*|text()"/>
			</dc:description>
		</xsl:if>
	</xsl:template>
	<xsl:template match="dcq:extent|dcq:medium">
		<xsl:copy>
			<xsl:apply-templates select="*|@*|text()"/>
		</xsl:copy>
		<xsl:if test="not(ancestor::dc:*
		|../dc:format[string()=string(current())]
		|preceding-sibling::dcq:extent[string()=string(current())]
		|preceding-sibling::dcq:medium[string()=string(current())])">
			<dc:format>
				<xsl:apply-templates select="*|@*|text()"/>
			</dc:format>
		</xsl:if>
	</xsl:template>
	<xsl:template match="dcq:spatial|dcq:temporal">
		<xsl:copy>
			<xsl:apply-templates select="*|@*|text()"/>
		</xsl:copy>
		<xsl:if test="not(ancestor::dc:*
		|../dc:coverage[string()=string(current())]
		|preceding-sibling::dcq:spatial[string()=string(current())]
		|preceding-sibling::dcq:temporal[string()=string(current())])">
			<dc:coverage>
				<xsl:apply-templates select="*|@*|text()"/>
			</dc:coverage>
		</xsl:if>
	</xsl:template>
	<xsl:template match="dcq:alternative">
		<xsl:copy>
			<xsl:apply-templates select="*|@*|text()"/>
		</xsl:copy>
		<xsl:if test="not(ancestor::dc:*
		|../dc:title[string()=string(current())]
		|preceding-sibling::dcq:alternative[string()=string(current())])">
			<dc:title>
				<xsl:apply-templates select="*|@*|text()"/>
			</dc:title>
		</xsl:if>
	</xsl:template>
	<xsl:template match="dcq:classification">
		<xsl:copy>
			<xsl:apply-templates select="*|@*|text()"/>
		</xsl:copy>
		<xsl:if test="not(ancestor::dc:*
		|../dc:subject[string()=string(current())]
		|preceding-sibling::dcq:classification[string()=string(current())])">
			<dc:subject>
				<xsl:apply-templates select="*|@*|text()"/>
			</dc:subject>
		</xsl:if>
	</xsl:template>
	<xsl:template match="dcq:mediator">
		<xsl:copy>
			<xsl:apply-templates select="*|@*|text()"/>
		</xsl:copy>
		<xsl:if test="not(ancestor::dc:*
		|../dc:audience[string()=string(current())]
		|preceding-sibling::dcq:mediator[string()=string(current())])">
			<dc:audience>
				<xsl:apply-templates select="*|@*|text()"/>
			</dc:audience>
		</xsl:if>
	</xsl:template>
	<xsl:template match="*|@*">
		<xsl:copy>
			<xsl:apply-templates select="*|@*|text()"/>
		</xsl:copy>
	</xsl:template>
</xsl:stylesheet>
