Search code examples
javascriptphpxmlxsltyahoo-api

How to display XML data from a url using XSLT


I've got dynamic XML sports data coming via a url in a Yahoo API that I want to display and sort a selection of on my website using XSLT. This is the first time playing with XML and XLST. While testing, I've worked out how to display it correctly when the XML code is manually pasted into a XML file on my server but I'm struggling with how to get the XML data feed (which is updated daily) from the url and on to the web page.

I have a PHP file where I'm connecting to the feed successfully and printing the raw XML data (call it 'feed.php'). I believe part of the issue is that the XML data is outputted in that file as a string so would need to be transformed into a document (object?) so the XSLT can interact with element tags in the XML. On the web page where I want to display a selection of the data:

<main>
    <button type="button" onclick="loadStandings(displayOverallStandings)">League Standings</button>
    
    <article id="standings-division">
*league standings to display here when the button is clicked*
    </article>

<script>

// found elsewhere on SO to turn string into XML document

function loadStandings(displayOverallStandings) {
    var xhr = new XMLHttpRequest();
    xhr.onload = function() {
    dump(xhr.responseXML.documentElement.nodeName);
}
    xhr.onerror = function() {
  dump("Error while getting XML.");
}
xhr.onreadystatechange = function () {
        if (this.readyState == 4 && this.status == 200) {
                displayOverallStandings(this);
        }
    }
xhr.open("GET", "feed.php"); // the path to the feed.php file
xhr.responseType = "document";
xhr.send();

}

// more code I found on SO to load xml and xsl docs in browser to display league standings

function displayOverallStandings(xhr) {

    xml = xhr.responseXML;
    xsl = loadXMLDoc("standings.xsl"); // path to the XSL file I've created
// code for IE
if (window.ActiveXObject || xhttp.responseType == "msxml-document")
  {
  ex = xml.transformNode(xsl);
  document.getElementById("standings-division").innerHTML = ex;
  }
// code for Chrome, Firefox, Opera, etc.
else if (document.implementation && document.implementation.createDocument)
  {
  xsltProcessor = new XSLTProcessor();
  xsltProcessor.importStylesheet(xsl);
  resultDocument = xsltProcessor.transformToFragment(xml, document);
  document.getElementById("standings-division").appendChild(resultDocument);
  }
}
</script>

UPDATE: As requested, here's the XSLT code:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
  <ol>
    <div class=''>
        <span>Team</span>
        <span>Points</span>
        <span>Points Change</span>
    </div>
    <xsl:for-each select="fantasy_content/leagues/league/standings/teams/team">
      <xsl:sort select="team_standings/points_for" data-type="number" order="descending"/>
      <li>
        <span><xsl:value-of select="name"/></span>
        <span><xsl:value-of select="team_standings/points_for"/></span>
        <span><xsl:value-of select="team_standings/points_change"/></span>
      </li>
    </xsl:for-each>
  </ol>
</xsl:template>

</xsl:stylesheet>

On the web page the html from the XSL file is displayed but no XML data is pulled through. I don't think it's an issue with the XSL file because, as I say, it displays correctly if in displayOverallStandings() I just load a 'static file' with the XML code pasted into.

Another cause of the issue might be that the root element in full XML code provided in the Yahoo feed included a load of additional info about the feed that I had to remove before even the 'static file' with the pasted-in XML code would display. This is it:

<?xml version="1.0" encoding="UTF-8"?>
<content xml:lang="en-US" yahoo:uri="*feed url*" time="399.72496032715ms" copyright="Data provided by Yahoo! and STATS, LLC" refresh_rate="60" xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" xmlns="http://fantasysports.yahooapis.com/fantasy/v2/base.rng">
* rest of the XML code *

But I don't know how to automatically strip out that stuff from the source feed url so it would just start <?xml version="1.0" encoding="UTF-8"?><content>... before the code above tries to display it with the XSLT.

Thanks for any help!


Solution

  • I found a workaround solution using PHP in the 'feed.php' file to turn the feed xml data into a Simple XML Object (which presents data as an array), loop through the array to select the specific data I want, then turn that back into xml tags using the SimpleXMLElement() function. This allows the creation of a simpler xml doc with the extraneous Yahoo blurb excluded from the tags, which behaves correctly with the XSLT.

    <?php
    (Feed data saved in $response variable)
    
    // convert xml data string into XML object
    $xml = simplexml_load_string($response);
    
    // selected output from object array as manually created XML tags
    $output = new SimpleXMLElement('<?xml version="1.0" encoding="utf-8"?><content></content>');
    $date = $output->addChild('date',$xml->date); //append 'date' xml tags and get the date content from the XML object
    
    (create more xml tags containing data, etc...)
    
    echo $output->asXML();
    
    ?>