<?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="&#xD;&#xA;"|<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="'&#xD;&#xA;'" />
  
  
  <!--  ================================================  -->
  <!--  ================================================  -->
  <!--  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(),'&#xD;&#xA;',''))" /></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(),'&#xD;&#xA;',''))" /></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                                               -->
  <!--  ================================================  -->