<?xml version="1.0" encoding="iso-8859-1"?> <!-- ================================================ --> <!-- ================================================ --> - <!-- ================================================ GEDCOM one-to-one to XML reverse transformation stylesheet (XML to GEDCOM) Copyright (c) 2008 ff. Stefan Unterstein <http://unterstein.net/ged1212xml> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License Version 3 or any later version published by the Free Software Foundation. See the current License at <http://www.gnu.org/licenses/gpl.html> for more details. The program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Limitations: 1. output-encoding is unicode (utf-8) and corresponding HEAD/CHAR/VERS tags are changed or omitted 2. loss of whitespace is possible due to normalization or default modes of the XSLT-processor 3. “@”s are not transformed to double “@@”s Covered/Defaults: 1. independent of root and namespace 2. elements S|SURN|SURNAME revert to slashed /surname/-part 3. attributes ID|REF|ESC and xml:id revert to @<XREF>@ or @#<DTOKEN>@ 4. removal of id-prefixes in a colon-ized namespace style, e.g. “nn:” in ID="nn:XREF" The stylesheet is parameterized to change the optional element- and attribute-names according to ged1212xml. ================================================ --> <!-- ================================================ --> <!-- ================================================ --> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" - > <xsl:output method="text" media-type="text/plain" encoding="utf-8" /> <!-- ================================================ --> <!-- ================================================ --> - <!-- stylesheet-parameters xmlID="ID"|<nmtoken> replace attribute-name's default "ID" for GEDCOM's @<XREF>@s xmlIDREF="REF"|<nmtoken> replace attribute-name's default "REF" for GEDCOM's @<XREF>@s escDATE="ESC"|<nmtoken> replace attribute-name's default "ESC" for GEDCOM's @#<DATE_CALENDAR_ESCAPE>@s surNAME="SURN"|<nmtoken> replace element-name's defaults "S|SURN|SURNAME" for GEDCOM's slashed /surname/ part idPFX=":"|<nmtoken> use string after token for GEDCOM's @<XREF>@s (remove prefix, e.g. "nn:" of ID="nn:XREF") colon-ized namespace style is covered/removed by default newline="
"|<newlinechar(s)> set line-endings CR+LF to system's default check your XSLT-processor's commandline usage how to set stylesheet-parameters ================================================ --> <!-- ================================================ --> <xsl:param name="xmlID" select="'ID'" /> <xsl:param name="xmlIDREF" select="'REF'" /> <xsl:param name="escDATE" select="'ESC'" /> <xsl:param name="surNAME" select="'SURN'" /> - <xsl:param name="idPFX"> <xsl:variable name="xmlIDs" select="count(/*/*/@*[local-name()=$xmlID])" /> - <xsl:choose> - <xsl:when test="count(/*/*/@*[local-name()=$xmlID and contains(.,':')])=$xmlIDs"> <xsl:value-of select="':'" /> <!-- get rid of any colon-ized id-prefix --> </xsl:when> <xsl:otherwise><xsl:value-of select="''" /></xsl:otherwise> </xsl:choose> </xsl:param> <xsl:param name="newline" select="'
'" /> <!-- ================================================ --> <!-- ================================================ --> <!-- elements *:HEAD/*:CHAR/*:VERS --> - <xsl:template match="/*/*[local-name()='HEAD']" priority="1"> <!-- don't start with (empty) newline --> <xsl:param name="level" select="0" /> <xsl:value-of select="concat($level,' HEAD')" /> - <xsl:apply-templates select="*"> <xsl:with-param name="level" select="$level+1"/> </xsl:apply-templates> </xsl:template> - <xsl:template match="/*/*[local-name()='HEAD']/*[local-name()='CHAR']" priority="1"> <!-- CHAR set to utf-8/UNICODE anyway --> <xsl:param name="level" select="0" /> <xsl:value-of select="concat($newline,$level,' CHAR UNICODE')" /> - <xsl:apply-templates select="*"> <xsl:with-param name="level" select="$level+1"/> </xsl:apply-templates> </xsl:template> <xsl:template match="/*/*[local-name()='HEAD']/*[local-name()='CHAR']/*[local-name()='VERS']" priority="1" /> <!-- ignore --> <!-- ================================================ --> <!-- ================================================ --> <!-- all text, all elements except root/* --> <xsl:template match="text()" /> <!-- only explicit text-processing --> - <xsl:template match="/*//*"> <xsl:param name="level" select="0" /> <xsl:value-of select="concat($newline,$level,' ',local-name())" /> <xsl:apply-templates select="@*" mode="attr" /> <xsl:if test="normalize-space(text())"><xsl:value-of select="concat(' ',translate(text(),'
',''))" /></xsl:if> - <xsl:apply-templates select="*"> <xsl:with-param name="level" select="$level+1"/> </xsl:apply-templates> </xsl:template> <!-- ================================================ --> <!-- ================================================ --> <!-- all attributes, local name parameterized --> - <xsl:template match="@*" mode="attr"> <!-- no variables in match allowed, so this --> - <xsl:choose> - <xsl:when test="local-name()=$xmlID or local-name()=$xmlIDREF"> <xsl:value-of select="concat(' @',substring-after(.,$idPFX),'@')" /> </xsl:when> - <xsl:when test="local-name()=$escDATE"> <xsl:value-of select="concat(' @#',.,'@')" /> </xsl:when> </xsl:choose> </xsl:template> - <xsl:template match="@xml:id" mode="attr"> <xsl:value-of select="concat(' @',substring-after(.,$idPFX),'@')" /> </xsl:template> <!-- ================================================ --> <!-- ================================================ --> <!-- *:NAME-subelement #1: S|SURN|SURNAME|$surNAME --> - <xsl:template match="*[local-name()='NAME' and not(contains(text()[1],'/'))]/*[1]" priority="1"> <xsl:param name="level" select="0" /> - <xsl:choose> - <xsl:when test="local-name()='S' or local-name()=$surNAME or local-name()='SURNAME'"> <xsl:value-of select="concat('/',.,'/')" /> </xsl:when> - <xsl:otherwise> <xsl:value-of select="concat($newline,$level,' ',local-name())" /> <xsl:apply-templates select="@*" mode="attr" /> <xsl:if test="normalize-space(text())"><xsl:value-of select="concat(' ',translate(text(),'
',''))" /></xsl:if> <xsl:apply-templates select="*"><xsl:with-param name="level" select="$level+1"/></xsl:apply-templates> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- ================================================ --> <!-- ================================================ --> - <!-- ================================================ ================================================ --> <!-- ================================================ --> <!-- ================================================ --> </xsl:stylesheet> <!-- ================================================ --> <!-- EOF --> <!-- ================================================ -->