<!-- XSLT Stylesheet "mondial.xsl":
  (Wolfgang May, may@informatik.uni-freiburg.de, March 2000; revised Dec 2006)
  transforms flat mondial-flat.xml according to mondial-flat.dtd into 
  a hierarchical model according to mondial.dtd.
  call:
  saxonXQ -o mondial.xml -s mondial-flat.xml mondial.xsl  -->

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                version="1.0">

<xsl:output method="xml" indent="yes"/>

<!-- \noindent
  The new document uses the external DTD file \emph{mondial.dtd}. 
  Note that this information is written by \verb|<xsl:text>| with   
  attribute \verb|disable-output-escaping="yes"|, replacing 
  \verb|&lt;| and \verb|&gt;| by the tag-delimiters \verb|<| and  
  \verb|>|. Then, the document contents is handled. -->

<xsl:template match="mondial">
  <xsl:text disable-output-escaping="yes">
       &lt;!DOCTYPE mondial SYSTEM "mondial.dtd"&gt;
  </xsl:text>
  <mondial>
  <xsl:apply-templates select="country"/>
  <xsl:apply-templates 
       select="continent|organization|
               river|lake|sea|mountain|desert|island|
               restriction"/>
  </mondial>
</xsl:template>

<!-- Here is a generic template which converts an attribute into a
  \verb|PCDATA| element. -->

<xsl:template match="@*">
<!-- an element of the type of the current element must be opened. -->
  <xsl:variable name="type" select="local-name()"/>
  <xsl:element name="{$type}"> 
     <xsl:value-of select="current()"/>
  </xsl:element>
</xsl:template>

<!-- \noindent
  For each country, the country information is copied. The car code
  is used as id.
  If administrative divisions are given - referenced inside the 
  \emph{adm\_divs} attribute - they become subelements of the country
  which in turn contain the cities as subelements. Note that the 
  provinces elements are explicitly selected by using the reference
  to their id. If for none of the cities the administrative division 
  is given, cities become direct children of the country (note that
  this covers both the case that no administrative divisions are known
  at all (e.g., Albania), or they are known but not associated with 
  cities.
-->

<xsl:template match="country">
  <country> 
    <xsl:attribute name="car_code"> 
      <xsl:choose>
       <xsl:when test="@car_code">
         <xsl:value-of select="@car_code"/>
       </xsl:when>
       <xsl:otherwise>
         <xsl:value-of select="@id"/>
       </xsl:otherwise>
     </xsl:choose>
    </xsl:attribute>
    <xsl:attribute name="area"> 
       <xsl:value-of select="@total_area"/>
    </xsl:attribute>
    <xsl:copy-of select="@capital"/>
    <xsl:if test="id(//organization/members/@country)/@id=current()/@id">
       <xsl:variable name="memberships">
          <xsl:for-each 
               select="//organization[id(members/@country)/@id=current()/@id]"> 
            <xsl:value-of select="current()/@id"/>
            <xsl:text> </xsl:text>
          </xsl:for-each> 
       </xsl:variable>
       <xsl:attribute name="memberships"> 
          <xsl:value-of select="normalize-space($memberships)"/>
       </xsl:attribute>
    </xsl:if>
    <xsl:apply-templates select="@name|@population|
               @population_growth|@infant_mortality|
               @gdp_total|@gdp_ind|@gdp_agri|@gdp_serv|
               @inflation|@indep_date|@government"/>
    <xsl:for-each select="encompassed">
      <encompassed>
        <xsl:attribute name="continent">
           <xsl:value-of select="@continent"/>
        </xsl:attribute>
        <xsl:attribute name="percentage">
           <xsl:value-of select="text()"/>
        </xsl:attribute>
      </encompassed> 
    </xsl:for-each>
    <xsl:apply-templates select="ethnicgroups|religions|languages"/>
    <xsl:for-each select="borders">
      <border>
        <xsl:attribute name="country"> 
          <xsl:choose>
            <xsl:when test="id(current()/@country)/@car_code">
              <xsl:value-of select="id(current()/@country)/@car_code"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="id(current()/@country)/@id"/>
            </xsl:otherwise>
          </xsl:choose>
        </xsl:attribute>
        <xsl:attribute name="length"> 
          <xsl:value-of select="text()"/>
        </xsl:attribute>
      </border>
    </xsl:for-each>
    <xsl:choose>
      <xsl:when test="@adm_divs">
        <xsl:apply-templates select="id(@adm_divs)">
          <xsl:with-param name="countrycap" select="@capital"/>   
        </xsl:apply-templates>
      </xsl:when>
    </xsl:choose>
    <xsl:apply-templates 
         select="/mondial/city[@country=current()/@id 
                               and (not (@province))]">
      <xsl:with-param name="countrycap" select="@capital"/>
    </xsl:apply-templates>
  </country> 
</xsl:template>

<xsl:template match="ethnicgroups|religions|languages">
  <xsl:variable name="type" select="local-name()"/>
  <xsl:element name="{$type}">
    <xsl:attribute name="percentage">
       <xsl:value-of select="text()"/>
    </xsl:attribute>
    <xsl:value-of select="@name"/>
  </xsl:element>
</xsl:template>

<!-- \noindent
 The following rule is applied to every province selected by the above rule.
 The province information is copied.  All cities which belong to this
 province become subelements.
 Here, the selection is controlled by comparing the \emph{in\_Province} 
 attribute of the cities with the id of the province currently under 
 consideration: -->

<xsl:template match="province">
    <xsl:param name="countrycap"/>
    <province>
      <xsl:copy-of select="@id|@capital"/>
      <xsl:attribute name="country">
        <xsl:choose>
          <xsl:when test="id(@country)/@car_code">
            <xsl:value-of select="id(@country)/@car_code"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="id(@country)/@id"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
      <xsl:apply-templates 
                 select="@name|@area|@population"/>
      <xsl:apply-templates 
                 select="/mondial/city[@province=current()/@id]">
           <xsl:with-param name="countrycap" select="$countrycap"/>
           <xsl:with-param name="statecap" select="@capital"/>
      </xsl:apply-templates>
    </province>
</xsl:template>

<!-- \noindent
  For every city (copied inside the province elements inside the country 
  elements), the city information is copied, and attributes
  \emph{is\_country\_cap} and \emph{is\_state\_cap} distinguish capitals.
  The waters where a city is located are also reformatted, defining a
  method which depends on the type of the water (using an XSLT variable).
-->

<xsl:template match="city">
    <xsl:param name="countrycap"/>
    <xsl:param name="statecap"/>
    <city>  
      <xsl:copy-of select="@id"/>
      <xsl:if test="@id=$countrycap">
           <xsl:attribute name="is_country_cap">yes</xsl:attribute>
      </xsl:if>
      <xsl:if test="@id=$statecap">
           <xsl:attribute name="is_state_cap">yes</xsl:attribute>
      </xsl:if>
      <xsl:attribute name="country">
        <xsl:choose>
          <xsl:when test="id(@country)/@car_code">
            <xsl:value-of select="id(@country)/@car_code"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="id(@country)/@id"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:attribute>
      <xsl:copy-of select="@province"/>
      <name><xsl:value-of select="@name"/></name>
      <xsl:apply-templates select="@longitude|@latitude"/>
      <xsl:copy-of select="population"/>
      <xsl:for-each select="located_at"> 
        <located_at>
          <xsl:variable name="temp" select="@watertype"/>
          <xsl:attribute name="watertype">
             <xsl:value-of select="$temp"/>
          </xsl:attribute>
          <xsl:attribute name="{$temp}">
             <xsl:value-of select="@water"/>
          </xsl:attribute>
         </located_at>
     </xsl:for-each> 
    </city>
</xsl:template>

<!-- \noindent continents: -->

<xsl:template match="continent">
  <continent>
    <xsl:copy-of select="@id"/>
    <xsl:apply-templates select="@name|@area"/>
  </continent>
</xsl:template>

<!-- \noindent organizations are restructured: -->

<xsl:template match="organization">
  <organization>
    <xsl:copy-of select="@id|@headq"/>
    <xsl:apply-templates select="@name|@abbrev|@established"/>
    <xsl:apply-templates select="members"/>
  </organization>
</xsl:template>

<xsl:template match="members">
  <members>
    <xsl:copy-of select="@type"/>
    <xsl:variable name="members">
      <xsl:for-each select="id(@country)">
        <xsl:choose>
          <xsl:when test="@car_code">
            <xsl:value-of select="@car_code"/>
          </xsl:when>
          <xsl:otherwise>
            <xsl:value-of select="@id"/>
          </xsl:otherwise>
        </xsl:choose>
        <xsl:text> </xsl:text>
      </xsl:for-each> 
    </xsl:variable>
    <xsl:attribute name="country">
      <xsl:value-of select="normalize-space($members)"/>
    </xsl:attribute>
  </members>
</xsl:template>

<!-- \noindent Geo objects are restructured. Take only those where
 the country they belong to is known. Note that the ids have to be
 changed from country ids to car-codes: -->

<xsl:template match="river|lake|sea|island|mountain|desert">
<!-- an element of the type of the current element must be opened. -->
  <xsl:if test="@country">
    <xsl:variable name="type" select="local-name()"/>
    <xsl:element name="{$type}"> 
      <xsl:copy-of select="@id"/>
      <xsl:variable name="countries"> 
        <xsl:for-each select="id(@country)">
          <xsl:choose>
            <xsl:when test="@car_code">
              <xsl:value-of select="@car_code"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:value-of select="@id"/>
            </xsl:otherwise>
          </xsl:choose>
          <xsl:text> </xsl:text>
        </xsl:for-each>
      </xsl:variable>
      <xsl:attribute name="country"> 
        <xsl:value-of select="normalize-space($countries)"/>
      </xsl:attribute>
      <xsl:copy-of select="@bordering"/>
      <xsl:copy-of select="to"/>

      <xsl:for-each select="located">
        <located>
          <xsl:attribute name="country"> 
            <xsl:choose>
              <xsl:when test="id(current()/@country)/@car_code">
                <xsl:value-of select="id(current()/@country)/@car_code"/>
              </xsl:when>
              <xsl:otherwise>
                <xsl:value-of select="id(current()/@country)/@id"/>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:attribute>
          <xsl:copy-of select="@province"/>
        </located>
      </xsl:for-each>

      <xsl:apply-templates select="@name|@islands|@area|
               @length|@height|@depth|@longitude|@latitude"/>

    </xsl:element>
  </xsl:if>
</xsl:template>

<!-- \noindent All other objects are copied: -->

<xsl:template match="restriction">
  <xsl:copy-of select="current()"/>
</xsl:template>

</xsl:stylesheet>
