deucalion0
deucalion0

Reputation: 2440

Use of XSD Duration type, using XSLT to out put value to normal duration format

I am storing a duration in my XML, in my Schema I have set this as a duration type:

<?xml version="1.0" encoding="UTF-8"?>

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
elementFormDefault="qualified" 
attributeFormDefault="unqualified">


<xs:element name="flights">
<xs:complexType>
  <xs:sequence>
    <xs:element name="flight" type="flighttype" minOccurs='1' maxOccurs='unbounded'>
      <xs:unique name="planeidisunique">
        <xs:selector xpath="plane"/>
        <xs:field xpath="@planeid"/>
      </xs:unique>
    </xs:element>
  </xs:sequence>
</xs:complexType>
<xs:unique name="flightidisunique">
  <xs:selector xpath="flight"/>
  <xs:field xpath="@flightid"/>
</xs:unique>
</xs:element>

<xs:complexType name="flighttype">
<xs:sequence>
    <xs:element name="flightno" type="xs:string" minOccurs="1" maxOccurs="1"/>
    <xs:element name="callsign" type="xs:string" minOccurs="1" maxOccurs="1"/>
    <xs:element name="airline" type="xs:string" minOccurs="1" maxOccurs="1"/>
    <xs:element name="plane" type="planetype" minOccurs='1' maxOccurs='unbounded' />
    <xs:element name="route" type="routetype"/>
</xs:sequence>
<xs:attribute name="flightid" type="xs:string"/>
</xs:complexType>

<!-- PLANE -->

<xs:complexType name="planetype" mixed="true">
<xs:sequence>
    <xs:element name="name" type="xs:string"/>
    <xs:element name="speed" type="speedtype"/>
    <xs:element name="wingspan" type="xs:string"/>
    <xs:element name="length" type="xs:string"/>
    <xs:element name="registereddate" type="xs:date"/>
</xs:sequence>
<xs:attribute name="planeid" type="xs:string"/>
</xs:complexType>


<!-- ALTITUDE -->

<xs:complexType name="altitudetype">
<xs:simpleContent>
  <xs:extension base="xs:integer">
    <xs:attribute name="height" type="xs:string">
    </xs:attribute>
  </xs:extension>
</xs:simpleContent>
</xs:complexType>


<!-- SPEED THE VALUE OF SPEED MUST BE AN INTEGER-->

<xs:complexType name="speedtype">
<xs:simpleContent>
  <xs:extension base="xs:integer">
    <xs:attribute name="ratio" type="xs:string">
    </xs:attribute>
  </xs:extension>
</xs:simpleContent>
</xs:complexType>



  <!-- DISTANCE VALUE OF DISTANCE MUST BE AN INTEGER-->

<xs:complexType name="distancetype">
<xs:simpleContent>
  <xs:extension base="xs:integer">
    <xs:attribute name="unit" type="xs:string">
    </xs:attribute>
  </xs:extension>
</xs:simpleContent>
  </xs:complexType>


<!-- COURSE -->

<xs:complexType name="coursetype">
<xs:simpleContent>
  <xs:extension base="xs:integer">
    <xs:attribute name="bearing" type="xs:string">
    </xs:attribute>
  </xs:extension>
</xs:simpleContent>
  </xs:complexType>



  <!-- DURATION -->

<xs:complexType name="durationtype">
<xs:simpleContent>
  <xs:extension base="xs:duration">
  </xs:extension>
</xs:simpleContent>
  </xs:complexType>



<!-- ROUTE -->


<xs:complexType name="routetype">
<xs:sequence>
    <xs:element name="routename" type="xs:string"/>
    <xs:element name="altitude" type="altitudetype" minOccurs="1" maxOccurs="1"/>
    <xs:element name="speed" type="speedtype" minOccurs="0" maxOccurs="1"/>
    <xs:element name="course" type="coursetype"/>
    <xs:element name="distance" type="distancetype"/>
    <xs:element name="duration" type="durationtype"/>
    <xs:element name="from" type="fromtype"/>
    <xs:element name="to" type="totype"/>
</xs:sequence>
</xs:complexType>



<!-- FROM -->

<xs:complexType name="fromtype">
<xs:sequence>
    <xs:element name="iatacode"/>
    <xs:element name="airport"/>
    <xs:element name="country"/>
    <xs:element name="city"/>
    <xs:element name="latitude"/>
    <xs:element name="longitude"/>
    <xs:element name="yahoowoeid"/>
</xs:sequence>
</xs:complexType>

<!-- TO -->

<xs:complexType name="totype">
<xs:sequence>
    <xs:element name="iatacode"/>
    <xs:element name="airport"/>
    <xs:element name="country"/>
    <xs:element name="city"/>
    <xs:element name="latitude"/>
    <xs:element name="longitude"/>
    <xs:element name="yahoowoeid"/>
</xs:sequence>
</xs:complexType>


</xs:schema>

In my XML I use duration like this:

<duration>PT12H37M</duration>

Here is my XSL file, I have put a comment in where I use the duration:

<?xml version="1.0"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" omit-xml-declaration="yes" />
<xsl:output doctype-public="-//WAPFORUM//DTD XHTML Mobile 1.0//EN" doctype-system="http://www.wapforum.org/DTD/xhtml-mobile10.dtd"/>

<!-- Parameters for the map longitudes and latitudes and route name-->
<xsl:param name="a" />
<xsl:param name="b" />
<xsl:param name="c" />
<xsl:param name="d" />

<xsl:template match="/">
    <xsl:element name="html">
        <xsl:element name="head">
            <xsl:element name="title">Selected Flight Route</xsl:element>
            <link rel="stylesheet" type="text/css" href="mystyles.css" title="Style"/>
        </xsl:element>

        <xsl:element name="body"> 

            <xsl:element name="div"><!-- This holds the navigation bar-->
                <xsl:attribute name="id">
                    <xsl:text>navdiv</xsl:text>
                </xsl:attribute>


                <xsl:element name="div"><!-- This holds the image links-->
                    <xsl:attribute name="id">
                        <xsl:text>navlinks</xsl:text>
                    </xsl:attribute>

                    <xsl:element name="a">
                        <xsl:attribute name="id">
                            <xsl:text>navlinksone</xsl:text>
                        </xsl:attribute>
                        <xsl:attribute name="href">flights.php</xsl:attribute>
                    </xsl:element>

                    <xsl:element name="a">
                        <xsl:attribute name="id">
                            <xsl:text>navlinkstwo</xsl:text>
                        </xsl:attribute>
                        <xsl:attribute name="href">planes.php</xsl:attribute>
                    </xsl:element>

                    <xsl:element name="a">
                        <xsl:attribute name="id">
                            <xsl:text>navlinksthree</xsl:text>
                        </xsl:attribute>
                        <xsl:attribute name="href">weatherfeed.php</xsl:attribute>
                    </xsl:element>

                </xsl:element>
            </xsl:element><!-- End the navigation bar-->

            <xsl:element name="div">
                <xsl:attribute name="id">mapdiv</xsl:attribute>
                <img width="300" height="270" src="http://maps.google.com/maps/api/staticmap?size=300x270&amp;zoom=1&amp;path=color:0xff0000ff|weight:4|{$a},{$b}|{$c},{$d}
                    &amp;markers=color%3ablue|label%3aA|
                    {$a},{$b}|&amp;markers=color%3agreen|label%3aB|{$c},{$d}
                    &amp;sensor=false" />
            </xsl:element>

            <xsl:element name="hr"></xsl:element>


            <!-- The following is the table which holds all of the map and route information -->
            <table><xsl:attribute name="class">tab</xsl:attribute>
                <tr>
                    <td colspan="3"><xsl:attribute name="class">top</xsl:attribute><xsl:value-of select="/flights/flight/route[routename/. = $code]/routename"/></td>
                    </tr>
                    <tr>
                    <td><xsl:attribute name="class">lside</xsl:attribute></td>
                    <td><xsl:attribute name="class">lside</xsl:attribute>From<img src="bm.png" height="18" width="12"/></td>
                    <td><xsl:attribute name="class">lside</xsl:attribute>To<img src="gm.png" height="18" width="12"/></td>
                    </tr>

                    <tr>
                    <td><xsl:attribute name="class">lside</xsl:attribute>City</td>
                    <td><xsl:attribute name="class">rside</xsl:attribute><xsl:value-of select="/flights/flight/route[routename/. = $code]/from/city"/></td>
                    <td><xsl:attribute name="class">rside</xsl:attribute><xsl:value-of select="/flights/flight/route[routename/. = $code]/to/city"/></td>
                    </tr>

                    <tr>
                    <td><xsl:attribute name="class">lside</xsl:attribute>IATA Code</td>
                    <td><xsl:attribute name="class">rside</xsl:attribute><xsl:value-of select="/flights/flight/route[routename/. = $code]/from/iatacode"/></td>
                    <td><xsl:attribute name="class">rside</xsl:attribute><xsl:value-of select="/flights/flight/route[routename/. = $code]/to/iatacode"/></td>
                    </tr>

                    <tr >
                    <td><xsl:attribute name="class">lside</xsl:attribute>Country</td>
                   <td><xsl:attribute name="class">rside</xsl:attribute><xsl:value-of select="/flights/flight/route[routename/. = $code]/from/country"/></td>
                    <td><xsl:attribute name="class">rside</xsl:attribute><xsl:value-of select="/flights/flight/route[routename/. = $code]/to/country"/></td>
                    </tr>

                    <tr>
                        <td><xsl:attribute name="class">lside</xsl:attribute>Weather</td>


                        <td><xsl:attribute name="class">rside</xsl:attribute>
                            <xsl:element name="a">
                                <xsl:attribute name="id">
                                    <xsl:text>weatherimagelinks</xsl:text>
                                </xsl:attribute>
                            <xsl:attribute name="href">weather.php?woeid=<xsl:value-of select="/flights/flight/route[routename/. = $code]/from/yahoowoeid" /></xsl:attribute>
                            </xsl:element>
                        </td>
                          <td><xsl:attribute name="class">rside</xsl:attribute>
                            <xsl:element name="a">
                                <xsl:attribute name="id">
                                    <xsl:text>weatherimagelinks</xsl:text>
                                </xsl:attribute>
                            <xsl:attribute name="href">weather.php?woeid=<xsl:value-of select="/flights/flight/route[routename/. = $code]/to/yahoowoeid" /></xsl:attribute>
                            </xsl:element>
                        </td>
                    </tr>
                    <tr>
                        <td><xsl:attribute name="class">lside</xsl:attribute>Distance</td>
                        <td colspan="2"><xsl:attribute name="class">rside</xsl:attribute><xsl:value-of select="/flights/flight/route[routename/. = $code]/distance"/><xsl:value-of select="/flights/flight/route[routename/. = $code]/distance/@unit"/></td>
                    </tr>
                    <tr>
                        <td><xsl:attribute name="class">lside</xsl:attribute>Course</td>
                        <td colspan="2"><xsl:attribute name="class">rside</xsl:attribute><xsl:value-of select="/flights/flight/route[routename/. = $code]/course"/><xsl:value-of select="/flights/flight/route[routename/. = $code]/course/@bearing"/></td>
                    </tr>
                    <tr>
                        <td><xsl:attribute name="class">lside</xsl:attribute>Airline</td>
                        <td colspan="2"><xsl:attribute name="class">rside</xsl:attribute><xsl:value-of select="/flights/flight/route[routename/. = $code]/../airline"/></td>
                    </tr>
                    <tr>
                        <td><xsl:attribute name="class">lside</xsl:attribute>Flight No</td>
                        <td colspan="2"><xsl:attribute name="class">rside</xsl:attribute><xsl:value-of select="/flights/flight/route[routename/. = $code]/../flightno"/></td>
                    </tr>
                    <tr>
                        <td><xsl:attribute name="class">lside</xsl:attribute>Call Sign</td>
                        <td colspan="2"><xsl:attribute name="class">rside</xsl:attribute><xsl:value-of select="/flights/flight/route[routename/. = $code]/../callsign"/></td>
                    </tr>
                    <tr>
<!-- THIS IS WHERE I OUTPUT THE DURATION AND I THINK THIS IS WHERE I NEED TO TRANSFORM IT -->
                        <td><xsl:attribute name="class">lside</xsl:attribute>Duration</td>
                        <td colspan="2"><xsl:attribute name="class">rside</xsl:attribute><xsl:value-of select="/flights/flight/route[routename/. = $code]/duration"/></td>
                    </tr>
                    <tr>
                        <td><xsl:attribute name="class">lside</xsl:attribute>Altitude</td>
                        <td colspan="2"><xsl:attribute name="class">rside</xsl:attribute><xsl:value-of select="/flights/flight/route[routename/. = $code]/altitude"/><xsl:value-of select="/flights/flight/route[routename/. = $code]/altitude/@height"/></td>
                    </tr>
                    <tr>
                        <td><xsl:attribute name="class">lside</xsl:attribute>Speed</td>
                        <td colspan="2"><xsl:attribute name="class">rside</xsl:attribute><xsl:value-of select="/flights/flight/route[routename/. = $code]/speed"/><xsl:value-of select="/flights/flight/route[routename/. = $code]/speed/@ratio"/></td>
                    </tr>




               <tr>
                    <td><xsl:attribute name="class">lside</xsl:attribute>Aircraft</td>
                     <td colspan="3">
                        <xsl:attribute name="class">lside</xsl:attribute>
                            <a><xsl:attribute name="href">aircraft.php?a=<xsl:value-of select="/flights/flight/plane[../route/routename/. =$code]/name" /></xsl:attribute>
                                <xsl:value-of select="/flights/flight/plane[../route/routename/. =$code]/name"/>
                            </a>
                    </td>
                </tr>

            </table>    
            <!-- End the map and route table -->

        </xsl:element>
        <!-- End the Body element -->

    </xsl:element>
    <!-- End the Html element -->

</xsl:template>
<!-- End the Main Template element -->

How can I transform the duration so it is normal on the screen, from PT12H37M to 12 h 37 m?

Upvotes: 0

Views: 2195

Answers (2)

Michael Kay
Michael Kay

Reputation: 163675

Firstly, your XSLT is incredibly verbose. Did you know? that instead of writing this:

            <xsl:element name="a">
                <xsl:attribute name="id">
                    <xsl:text>navlinkstwo</xsl:text>
                </xsl:attribute>
                <xsl:attribute name="href">planes.php</xsl:attribute>
            </xsl:element>

you can write this:

<a id="navlinkstwo" href="planes.php"/>

Secondly, you haven't said how it is failing. Martin has guessed that perhaps you are not using an XSLT 2.0 processor, but that seems to be pure guesswork based on no evidence. If you told us how it failed, we wouldn't have to guess.

Upvotes: 2

Martin Honnen
Martin Honnen

Reputation: 167781

Do you want to use an XSLT 2.0 processor like Saxon 9 or AltovaXML or XmlPrime?

In that case you can use

<xsl:template match="duration">
  <xsl:variable name="d" select="xs:dayTimeDuration(.)"/>
  <xsl:value-of select="concat(days-from-duration($d), ' h ', minutes-from-duration($d), ' m')"/>
</xsl:template>

See http://www.w3.org/TR/xpath-functions/#func-minutes-from-duration.

If you want to stick with your single template stylesheet then replace

                    <tr>
<!-- THIS IS WHERE I OUTPUT THE DURATION AND I THINK THIS IS WHERE I NEED TO TRANSFORM IT -->
                        <td><xsl:attribute name="class">lside</xsl:attribute>Duration</td>
                        <td colspan="2"><xsl:attribute name="class">rside</xsl:attribute><xsl:value-of select="/flights/flight/route[routename/. = $code]/duration"/></td>
                    </tr>

with

                    <tr>
<!-- THIS IS WHERE I OUTPUT THE DURATION AND I THINK THIS IS WHERE I NEED TO TRANSFORM IT -->
                        <td class="lside">Duration</td>
                        <xsl:variable name="d" select="xs:dayTimeDuration(/flights/flight/route[routename/. = $code]/duration)" xmlns:xs="http://www.w3.org/2001/XMLSchema"/>
                        <td colspan="2" class="rside"><xsl:value-of select="concat(days-from-duration($d), ' h ', minutes-from-duration($d), ' m')"/></td>
                    </tr>

Upvotes: 1

Related Questions