Search code examples
xsltcoordinate-systemsgeography

Conversion of geo coordinates from degree-hour-minutes to decimal in XSL


I have a XML file where one of the element is Geo-coordinate (Latitude/Longitude). This field is in degree-hour-minutes(eg: 43:06:35.4779) format and I need to convert it to decimal format. Can anyone help to do this conversion in XSL or point to some materials. Thanks in advance!

Edits: Can anyone help me to truncate the lat/long value I get after conversion. eg

<latitude>43.051643999999996</latitude>
<longitude>-112.62663475000001</longitude>

Solution

  • This transformation:

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>
    
     <xsl:template match="node()|@*">
      <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
      </xsl:copy>
     </xsl:template>
    
     <xsl:template match="lat/text() | long/text()">
      <xsl:call-template name="DegreesToDecimal"/>
     </xsl:template>
    
     <xsl:template name="DegreesToDecimal">
      <xsl:param name="pDegrees" select="."/>
    
      <xsl:variable name="vDegrees" select=
       "number(substring-before($pDegrees, ':'))"/>
    
      <xsl:variable name="vMinutes" select=
       "number(
           substring-before(
               substring-after($pDegrees, ':'),
               ':'
                           )
               )"/>
    
      <xsl:variable name="vSeconds" select=
       "number(
           substring-after(
               substring-after($pDegrees, ':'),
               ':'
                           )
               )"/>
    
      <xsl:value-of select=
       "$vDegrees
      +
        $vMinutes div 60
      +
        $vSeconds div 3600
      "/>
     </xsl:template>
    </xsl:stylesheet>
    

    when applied on this XML document:

    <coordinates>
     <lat>43:06:35.4779</lat>
     <long>53:22:16.7890</long>
    </coordinates>
    

    produces the wanted, correct result:

    <coordinates>
       <lat>43.10985497222222</lat>
       <long>53.37133027777778</long>
    </coordinates>
    

    Explanation: Proper use of the substring-before(), substring-after() and number() functions.