1

I need to create a table in html from an XSLT file, but selecting only a specific group of nodes. For example in the following XML I wish to select all of the from and to child nodes where routename contains fco-dxb:

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

<flights
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="flights.xsd">

<flight flightid="1">
    <flightno>EK98</flightno>
    <callsign>UAE98</callsign>
    <airline>Emirates Airline</airline>

    <plane planeid="1">
        <name>Airbus A380-861</name>

        <registereddate>07-06-10</registereddate>
    </plane>


    <registration>3A6-EDJ</registration>
    <altitude height="feet">41000</altitude>
    <speed ratio="mph">564</speed>
    <distance unit="miles">erf</distance>

    <route>
    <routename>FCO-DXB</routename>
        <from>
            <iatacode>FCO</iatacode>
            <airport>Fiumicino</airport>
            <country>Italy</country>
            <city>Rome</city>
            <latitude>41.8044</latitude>
            <longitude>12.2508</longitude>
        </from>

        <to>
            <iatacode>DXB</iatacode>
            <airport>Dubai Intl</airport>
            <country>United Arab Emirates</country>
            <city>Dubai</city>
            <latitude>25.2528</latitude>
            <longitude>55.3644</longitude>
        </to>
    </route>

    <course bearing="degrees">154</course>

    <journey>
        <distance type="miles">2,697</distance> 
        <time>PT5H30M</time>
    </journey>

</flight>


<flight flightid="2">
    <flightno>BA283</flightno>
    <callsign>BAW283</callsign>
    <airline>British Airways</airline>

    <plane planeid="2">
        <name>Boeing 747-436</name>
        <registereddate>06-12-97</registereddate>
    </plane>


    <registration>3A6-EDJ</registration>
    <altitude height="feet">41000</altitude>
    <speed ratio="mph">564</speed>
    <distance unit="miles">erf</distance>

    <route>
    <routename>LHR-LAX</routename>
        <from>
            <iatacode>LHR</iatacode>
            <airport>Heathrow</airport>
            <country>England</country>
            <city>London</city>
            <latitude>51.4775</latitude>
            <longitude>0.4614</longitude>
        </from>

        <to>
            <iatacode>LAX</iatacode>
            <airport>Los Angeles International</airport>
            <country>United States of America</country>
            <city>L.A</city>
            <latitude>33.9471</latitude>
            <longitude>-118.4082</longitude>
        </to>
    </route>

    <course bearing="degrees">154</course>

    <journey>
        <distance type="miles">5,441 miles</distance> 
        <time>PT11H5M</time>
    </journey>

</flight>




</flights>

and output this in a table, here is my attempt in the XSLT:

<?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:template match="/">
    <xsl:element name="html">
        <xsl:element name="head">
            <xsl:element name="title">flights</xsl:element>
        </xsl:element>


  <xsl:element name="body"> 
      <xsl:element name="table"><xsl:attribute name="border">1</xsl:attribute>
        <xsl:element name="tr">
          <xsl:element name="td">
            <xsl:element name="b">Title</xsl:element>
          </xsl:element>
          <xsl:element name="td">
            <xsl:element name="b">Artist</xsl:element>
          </xsl:element>
          <xsl:element name="td">
            <xsl:element name="b">Year</xsl:element>
          </xsl:element>
        </xsl:element>
        <xsl:apply-templates select="flights/flight/route[contains(text(), 'FCO-DXB')]" />
      </xsl:element>
    </xsl:element>
</xsl:element>
</xsl:template>


<xsl:template match="from">
<xsl:element name="tr">
  <xsl:element name="td"><xsl:value-of select="iatacode"/></xsl:element>
  <xsl:element name="td"><xsl:value-of select="airport"/></xsl:element>
  <xsl:element name="td"><xsl:value-of select="country"/></xsl:element>
  <xsl:element name="td"><xsl:value-of select="city"/></xsl:element>
</xsl:element>
</xsl:template>

<xsl:template match="to">
<xsl:element name="tr">
<xsl:element name="td"><xsl:value-of select="iatacode"/></xsl:element>
  <xsl:element name="td"><xsl:value-of select="airport"/></xsl:element>
  <xsl:element name="td"><xsl:value-of select="country"/></xsl:element>
  <xsl:element name="td"><xsl:value-of select="city"/></xsl:element>
</xsl:element>
</xsl:template>


</xsl:stylesheet>

My goal is to eventually figure out how to pass parameters to the XSLT file so instead of hardcoding the contains text, I can pass it a parameter, but so far I would just like to know how to answer this question.

1 Answer 1

3

You did not say if there can be more than one routename with the same identifier. And if there are, they should be displayed in the same table or in a different table (one per match)?

I assume here that if there are multiple routenames with the same identifier, those are printed in the same table (correct me if this assumption is not right and I will change the code accordingly).

This is one way of doing what you are trying to achieve:

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

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

<xsl:output method="html" omit-xml-declaration="yes" />

<xsl:param name="code"
           select="'FCO-DXB'" />

<xsl:template match="/flights">
    <html>
        <head>
            <title>flights</title>
        </head>
        <body>
            <xsl:apply-templates select="flight/route[routename/. = $code]" />
        </body>
    </html>
</xsl:template>


<xsl:template match="route">
    <table>
        <tr>
            <td><b>IATA Code</b></td>
            <td><b>Airport</b></td>
            <td><b>Country</b></td>
            <td><b>City</b></td>
        </tr>
        <xsl:apply-templates select="*" />
    </table>
</xsl:template>

<xsl:template match="from|to">
    <tr><xsl:apply-templates select="*" /></tr>
</xsl:template>

<xsl:template match="iatacode|airport|country|city">
    <td><xsl:value-of select="." /></td>
</xsl:template>

<xsl:template match="text()" />

</xsl:stylesheet>
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you for your answer. Sorry, there will only be one routename with that text. Your code does what I want but it creates the table headers twice, I would like all the information to be in one table, is this possible? Thanks a lot, your code is a lot better than what I had! :)
That should work as expected. I also updated the solution to accept a param, which value could be set by the XSLT processor before parsing the XML (depending on the XSLT processor).
Thanks, I will try that! I added my complete XML file. Basically, I just want a table that contains all of the from data and to data for the selected routename. Thank you!
I updated the answer, so now it is adapted to the updated XML file.
The output that I get from the XSLT is the one that you described, so it must be something else on the PHP file.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.