JeniT's xslt
authorDan Brickley <danbri@danbri.org>
Wed, 11 Apr 2012 17:24:47 +0200
changeset 19 5714a4f4f6f2
parent 18 0bb6f6823c45
child 20 dbc5b5fdbfb1
JeniT's xslt
schema.org/drafts/examples/microdata2rdfalite.xsl
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/schema.org/drafts/examples/microdata2rdfalite.xsl	Wed Apr 11 17:24:47 2012 +0200
@@ -0,0 +1,208 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!-- from jenit ... needs wf xml as input ... -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+	xmlns:xs="http://www.w3.org/2001/XMLSchema"
+	xmlns:h="http://www.w3.org/1999/xhtml" 
+	exclude-result-prefixes="xs h"
+	xmlns="http://www.w3.org/1999/xhtml"
+	version="2.0">
+
+<xsl:param name="allow-resource" as="xs:boolean" select="true()" />
+
+<!-- built-in prefixes from http://www.w3.org/2011/rdfa-context/rdfa-1.1.html -->
+<xsl:variable name="namespaces" as="element(ns)+" xmlns="">
+	<ns prefix="grddl">http://www.w3.org/2003/g/data-view#</ns>
+	<ns prefix="owl">http://www.w3.org/2002/07/owl#</ns>
+	<ns prefix="rdf">http://www.w3.org/1999/02/22-rdf-syntax-ns#</ns>
+	<ns prefix="rdfa">http://www.w3.org/ns/rdfa#</ns>
+	<ns prefix="rdfs">http://www.w3.org/2000/01/rdf-schema#</ns>
+	<ns prefix="rif">http://www.w3.org/2007/rif#</ns>
+	<ns prefix="skos">http://www.w3.org/2004/02/skos/core#</ns>
+	<ns prefix="skosxl">http://www.w3.org/2008/05/skos-xl#</ns>
+	<ns prefix="wdr">http://www.w3.org/2007/05/powder#</ns>
+	<ns prefix="void">http://rdfs.org/ns/void#</ns>
+	<ns prefix="wdrs">http://www.w3.org/2007/05/powder-s#</ns>
+	<ns prefix="xhv">http://www.w3.org/1999/xhtml/vocab#</ns>
+	<ns prefix="xml">http://www.w3.org/XML/1998/namespace</ns>
+	<ns prefix="xsd">http://www.w3.org/2001/XMLSchema#</ns>
+	<ns prefix="cc">http://creativecommons.org/ns#</ns>
+	<ns prefix="ctag">http://commontag.org/ns#</ns>
+	<ns prefix="dc">http://purl.org/dc/terms/</ns>
+	<ns prefix="foaf">http://xmlns.com/foaf/0.1/</ns>
+	<ns prefix="gr">http://purl.org/goodrelations/v1#</ns>
+	<ns prefix="ical">http://www.w3.org/2002/12/cal/icaltzd#</ns>
+	<ns prefix="og">http://ogp.me/ns#</ns>
+	<ns prefix="rev">http://purl.org/stuff/rev#</ns>
+	<ns prefix="sioc">http://rdfs.org/sioc/ns#</ns>
+	<ns prefix="v">http://rdf.data-vocabulary.org/#</ns>
+	<ns prefix="vcard">http://www.w3.org/2006/vcard/ns#</ns>
+	<ns prefix="schema">http://schema.org/</ns>
+</xsl:variable>
+
+<xsl:template match="node()|@*">
+	<xsl:copy>
+		<xsl:apply-templates select="@*|node()" />
+	</xsl:copy>
+</xsl:template>
+
+<xsl:template match="*[@itemprop and @itemid and not($allow-resource)]" priority="10">
+	<xsl:element name="{if (self::h:a) then 'span' else local-name()}">
+		<xsl:attribute name="rel" select="@itemprop" />
+		<xsl:copy>
+			<xsl:apply-templates select="@* except @itemprop" />
+			<xsl:apply-templates select="node()" />
+		</xsl:copy>
+	</xsl:element>
+</xsl:template>
+
+<xsl:template match="*[@itemscope]">
+	<xsl:variable name="types" as="xs:string*" select="tokenize(@itemtype, '\s')" />
+	<xsl:variable name="type" as="xs:string?" select="$types[1]" />
+	<xsl:variable name="vocab" as="xs:string" 
+		select="if (empty($type)) then '#' else if (contains($type, '#')) then concat(substring-before($type, '#'), '#') else replace($type, '[^/]+$', '')" />
+	<xsl:variable name="about" as="xs:string?" 
+		select="if (h:contains-changed-subject-nodes(.)) then if (@itemid) then @itemid else concat('_:', generate-id()) else ()" />
+	<xsl:copy>
+		<xsl:choose>
+			<xsl:when test="exists($about) and @itemprop and not($allow-resource)">
+				<xsl:attribute name="rel" select="@itemprop" />
+				<xsl:element name="{if (self::a) then 'span' else local-name(.)}">
+					<xsl:attribute name="about" select="$about" />
+					<xsl:apply-templates select="@*|node()">
+						<xsl:with-param name="containsRel" select="exists(.//@rel)" tunnel="yes" />
+						<xsl:with-param name="about" select="$about" tunnel="yes" />
+						<xsl:with-param name="vocab" select="$vocab" tunnel="yes" />
+						<xsl:with-param name="inItem" select="true()" tunnel="yes" />
+					</xsl:apply-templates>
+				</xsl:element>
+			</xsl:when>
+			<xsl:otherwise>
+				<xsl:if test="exists($about)">
+					<xsl:choose>
+						<xsl:when test="$allow-resource">
+							<xsl:attribute name="resource" select="$about" />
+						</xsl:when>
+						<xsl:otherwise>
+							<xsl:attribute name="about" select="$about" />
+						</xsl:otherwise>
+					</xsl:choose>
+				</xsl:if>
+				<xsl:apply-templates select="@*|node()">
+					<xsl:with-param name="containsRel" select="exists(.//@rel)" tunnel="yes" />
+					<xsl:with-param name="about" select="$about" tunnel="yes" />
+					<xsl:with-param name="vocab" select="$vocab" tunnel="yes" />
+					<xsl:with-param name="inItem" select="true()" tunnel="yes" />
+				</xsl:apply-templates>
+			</xsl:otherwise>
+		</xsl:choose>
+	</xsl:copy>
+</xsl:template>
+
+<xsl:template match="*[@href and @rel]">
+	<xsl:next-match>
+		<xsl:with-param name="inHref" select="true()" tunnel="yes" />
+	</xsl:next-match>
+</xsl:template>
+
+<xsl:template match="@href">
+	<xsl:param name="inItem" as="xs:boolean" select="false()" tunnel="yes" />
+	<xsl:if test="$inItem and not(../@property)">
+		<xsl:attribute name="property" />
+	</xsl:if>
+	<xsl:next-match />
+</xsl:template>
+
+<xsl:template match="@itemscope" />
+
+<xsl:template match="@itemtype">
+	<xsl:param name="vocab" as="xs:string" tunnel="yes" required="yes" />
+	<xsl:param name="containsRel" as="xs:boolean" tunnel="yes" required="yes" />
+	<xsl:if test="not($containsRel)">
+		<xsl:attribute name="vocab" select="$vocab" />
+	</xsl:if>
+	<xsl:attribute name="typeof">
+		<xsl:for-each select="tokenize(., '\s')">
+			<xsl:variable name="t" as="xs:string" select="." />
+			<xsl:variable name="ns" as="element(ns)?" select="$namespaces[starts-with($t, .)]" />
+			<xsl:sequence select="if (not($containsRel) and starts-with($t, $vocab)) then substring-after($t, $vocab) else if (exists($ns)) then concat($ns/@prefix, ':', substring-after($t, $ns)) else $t" />
+		</xsl:for-each>
+		<xsl:if test="position() != last()">
+			<xsl:text> </xsl:text>
+		</xsl:if>
+	</xsl:attribute>
+</xsl:template>
+
+<xsl:template match="*[$allow-resource]/@itemid">
+	<xsl:attribute name="resource" select="." />
+</xsl:template>
+
+<xsl:template match="@itemid">
+	<xsl:attribute name="about" select="." />
+</xsl:template>
+
+<xsl:template match="@itemprop">
+	<xsl:param name="about" as="xs:string?" tunnel="yes" required="yes" />
+	<xsl:param name="vocab" as="xs:string" tunnel="yes" required="yes" />
+	<xsl:param name="containsRel" as="xs:boolean" tunnel="yes" required="yes" />
+	<xsl:if test="../@href and ../@rel">
+		<xsl:choose>
+			<xsl:when test="$allow-resource">
+				<xsl:attribute name="resource" select="$about" />
+			</xsl:when>
+			<xsl:otherwise>
+				<xsl:attribute name="data-error" select="'href and rel'" />
+			</xsl:otherwise>
+		</xsl:choose>
+	</xsl:if>
+	<xsl:attribute name="property">
+		<xsl:for-each select="tokenize(., '\s')">
+			<xsl:variable name="p" as="xs:string" select="if (contains(., ':')) then . else if ($containsRel) then concat($vocab, .) else ." />
+			<xsl:variable name="ns" as="element(ns)?" select="$namespaces[starts-with($p, .)]" />
+			<xsl:sequence select="if (exists($ns)) then concat($ns/@prefix, ':', substring-after($p, $ns)) else $p" />
+			<xsl:if test="position() != last()">
+				<xsl:text> </xsl:text>
+			</xsl:if>
+		</xsl:for-each>
+	</xsl:attribute>
+	<xsl:if test="../@itemscope and not(../@itemtype)">
+		<xsl:attribute name="typeof" />
+	</xsl:if>
+</xsl:template>
+
+<xsl:function name="h:contains-changed-subject-nodes" as="xs:boolean">
+	<xsl:param name="element" as="element()" />
+	<xsl:variable name="children-contain-changed-subject-nodes" as="xs:boolean*">
+		<xsl:apply-templates select="$element/*" mode="h:contains-changed-subject-nodes" />
+	</xsl:variable>
+	<xsl:sequence select="$children-contain-changed-subject-nodes = true()" />
+</xsl:function>
+
+<xsl:template match="*[@itemprop]" mode="h:contains-changed-subject-nodes" as="xs:boolean" priority="10">
+	<xsl:param name="in-href" as="xs:boolean" tunnel="yes" select="false()" />
+	<xsl:choose>
+		<xsl:when test="$in-href">
+			<xsl:sequence select="true()" />
+		</xsl:when>
+		<xsl:otherwise>
+			<xsl:next-match />
+		</xsl:otherwise>
+	</xsl:choose>
+</xsl:template>
+
+<xsl:template match="*[@itemscope]" mode="h:contains-changed-subject-nodes" as="xs:boolean" priority="5">
+	<xsl:sequence select="false()" />
+</xsl:template>
+
+<xsl:template match="*" mode="h:contains-changed-subject-nodes" as="xs:boolean">
+	<xsl:param name="in-href" as="xs:boolean" tunnel="yes" select="false()" />
+	<xsl:variable name="children-contain-changed-subject-nodes" as="xs:boolean*">
+		<xsl:apply-templates select="*" mode="h:contains-changed-subject-nodes">
+			<xsl:with-param name="in-href" select="$in-href or (@href and @rel)" tunnel="yes" />
+		</xsl:apply-templates>
+	</xsl:variable>
+	<xsl:sequence select="$children-contain-changed-subject-nodes = true()" />
+</xsl:template>
+
+</xsl:stylesheet>