Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 11 of 11
  1. #1
    New Coder
    Join Date
    Jul 2011
    Posts
    40
    Thanks
    16
    Thanked 0 Times in 0 Posts

    PHP XSLT for styling, but picture url in XML file gives a challenge

    Hi,
    I am using XSLT to style a XML data. The data includes pictures which are presented this way:
    PHP Code:
    <weatherIconUrl>
    <![
    CDATA[
    http://www.worldweatheronline.com/images/wsymbols01_png_64/wsymbol_0002_sunny_intervals.png
    ]]>
    </
    weatherIconUrl

    Using only PHP, things work well, but the pictures come one under another one. While the purpose is to have them next to each other.

    With php to show a picture the way the XML source gives it goes like this:
    PHP Code:
    $picture=$item->weatherIconUrl;
    $line preg_replace('#<!\[CDATA\[.*?\]\]>#s'''$picture);
    echo 
    "<img src='$line' /> <br />"




    The PHP XSLT combination work some other way. I wonder which way?

    The working PHP code is:
    PHP Code:
    <html><head></head>
    <body>
    <?php
    $xslDoc 
    = new DOMDocument();
    $xslDoc->load("filename.xsl"); //Here comes to XSL file name
     
    $xmlDoc = new DOMDocument();
    $xmlDoc->load("http://free.worldweatheronline.com/feed/weather.ashx?q=milan,italy&format=xml&num_of_days=5&key=af8b2fc417222733111712");
     
    $proc = new XSLTProcessor();
    $proc->importStylesheet($xslDoc);
    echo 
    $proc->transformToXML($xmlDoc);
    ?>
    </body>
    </html>
    The working XSL code is:
    PHP Code:
    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="data">
    <table>
    <tr>
    <td>
    <p><xsl:value-of select="weather[1]/date"/> </p>
    <p><xsl:value-of select="weather[1]/weatherIconUrl"/></p>
    <hr />
    </td>
    <td>
    <p><xsl:value-of select="weather[2]/date"/> </p>
    <p><xsl:value-of select="weather[2]/weatherIconUrl"/></p>
    <hr />
    </td>
    </tr>
    </table>
    </xsl:template>
    </xsl:stylesheet>
    This bit of code shows the picture URLs but not the pictures. How to get the pictures visible?
    Last edited by Spookster; 01-05-2012 at 08:27 PM.

  • #2
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,978
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    These aren't images, they are only text. You need to put them in an img tag in order to have them parsed by HTML as an image.
    You don't need to use the preg replace at all here. CDATA blocks are an XML indicator for textual data that will not be parsed by the XML processor. Images are a bit of a pain in xsl, so I'll break this down as smaller template matches:
    Code:
    <?xml version="1.0"?>
    <?xml-stylesheet type="text/xsl" href="weathertest.xsl"?>
    <data>
    	<weather>
    		<date>Today</date>
    <weatherIconUrl>
    <![CDATA[
    http://www.worldweatheronline.com/images/wsymbols01_png_64/wsymbol_0002_sunny_intervals.png
    ]]>
    </weatherIconUrl>
    	</weather>
    	<weather>
    		<date>Tomorrow</date>
    <weatherIconUrl>
    <![CDATA[
    http://www.worldweatheronline.com/images/wsymbols01_png_64/wsymbol_0002_sunny_intervals.png
    ]]>
    </weatherIconUrl>
    	</weather>
    </data>
    Data above assumed on the xslt you have.

    My weathertest.xsl:
    Code:
    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="data">
        <table>
            <tr>
                <xsl:apply-templates />
            </tr>
        </table>
    </xsl:template>
    
    <xsl:template match="weather">
        <td>
            <p><xsl:value-of select="./date" /></p>
            <p><xsl:apply-templates select="./weatherIconUrl" /></p>
        </td>
    </xsl:template>
    
    <xsl:template match="weatherIconUrl">
        <img>
            <xsl:attribute name="src">
                <xsl:value-of select="." />
            </xsl:attribute>
        </img>
    </xsl:template>
    </xsl:stylesheet>
    And all done. I didn't bother with PHP in this case, but its results should be the same.

  • Users who have thanked Fou-Lu for this post:

    JonesJ (12-30-2011)

  • #3
    New Coder
    Join Date
    Jul 2011
    Posts
    40
    Thanks
    16
    Thanked 0 Times in 0 Posts
    Thank you Fou-Lu for the answer. There are two more questions on the same topic.

    The code works as it is below, but browser shows an unwanted line of code at the very top of the page.

    Another thing is the dates on top of the pictures. I would like to have the dates as a weekdays. With XPath functions it seems to be possible to have a day number; like 21. But how to change it to for example to 'Wednesday'?

    Working PHP:
    PHP Code:
    <html><head><title> </title></head>
    <body>
    <?php
    $xslDoc 
    = new DOMDocument();
    $xslDoc->load("weathertest.xsl");
     
    $xmlDoc = new DOMDocument();
    $xmlDoc->load("http://free.worldweatheronline.com/feed/weather.ashx?q=milan,italy&format=xml&num_of_days=5&key=af8b2fc417222733111712");
     
    $proc = new XSLTProcessor();
    $proc->importStylesheet($xslDoc);
    echo 
    $proc->transformToXML($xmlDoc);
    ?>
    </body>
    </html>


    Working XSLT:
    PHP Code:
    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="data">
    <table>
    <tr>
    <xsl:apply-templates />
    </tr>
    </table>
    </xsl:template>
     
    <xsl:template match="weather">
    <td>
    <p><xsl:value-of select="./date" /></p>
    <p><xsl:apply-templates select="./weatherIconUrl" /></p>
    </td>
    </xsl:template>
     
    <xsl:template match="weatherIconUrl">
    <img>
    <xsl:attribute name="src">
    <xsl:value-of select="." />
    </xsl:attribute>
    </img>
    </xsl:template>
    </xsl:stylesheet>
    Last edited by Spookster; 01-05-2012 at 08:28 PM. Reason: Fixed code tags

  • #4
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,978
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    This will be interesting. XSL itself has the ability to modify the date format in 2.0, but PHP will be dependent on libxslt version.
    Rather than rely on the version of XSL 2.0 being available, I'd say stick to a PHP route to do this by registering a PHP function instead. The XML guys would be able to verify if you can fetch just the text itself out of the node in XSLT, but I can't seem to get it to work. So I'll have to write a custom function instead to pull the node value out to format it (otherwise I could directly call date() and strtotime()).
    I used this. I pulled out the current weather since it was not meant to be parsed with the rest, but shares some common elements to match. You'll need to write a specific template and a call for it yourself. This is what I used, should be compatible with 5.1+ with an xslt 1.0 processor:
    PHP Code:
    <?php

    function dateToDayOfWeek($xmlDate$useFormat 'l')
    {
        
    $rd 'Unknown';
        if (
    count($xmlDate) == 1)
        {
            
    $element $xmlDate[0];
            if (
    $element instanceof DOMElement)
            {
                
    $rd date($useFormatstrtotime($element->nodeValue));
            }
        }
        return 
    $rd;
    }

    date_default_timezone_set('UTC');

    $xslDoc = new DOMDocument();
    $xslDoc->load("weathertest.xsl");

    $xmlDoc = new DOMDocument();
    $xmlDoc->load("http://free.worldweatheronline.com/feed/weather.ashx?q=milan,italy&format=xml&num_of_days=5&key=af8b2fc417222733111712");

    $proc = new XSLTProcessor();
    $proc->registerPHPFunctions('dateToDayOfWeek');
    $proc->importStylesheet($xslDoc);
    echo 
    $proc->transformToXML($xmlDoc);
    ?>
    Code:
    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl">
    <xsl:template match="data">
    <html>
    	<head><title>Weather</title></head>
    	<body>
    		<table border="1">
    			<tr>
    				<xsl:apply-templates select="./weather" />
    			</tr>
    		</table>
    	</body>
    </html>
    </xsl:template>
    
    <xsl:template match="weather">
    	<td>
    		<p><xsl:value-of select="php:function('dateToDayOfWeek', date)" /></p>
    		<p><xsl:apply-templates select="./weatherIconUrl" /></p>
    	</td>
    </xsl:template>
    
    <xsl:template match="weatherIconUrl">
    	<img>
    		<xsl:attribute name="src">
    		<xsl:value-of select="." />
    		</xsl:attribute>
    	</img>
    </xsl:template>
    
    </xsl:stylesheet>

  • Users who have thanked Fou-Lu for this post:

    JonesJ (12-30-2011)

  • #5
    New Coder
    Join Date
    Jul 2011
    Posts
    40
    Thanks
    16
    Thanked 0 Times in 0 Posts
    Hi,
    I tried this method to receive weather data for Celsius and Fahrenheit. There are two times these same codes, one set for Celsius and one set for Fahrenheit. The page starts with Celsius and there is a button to switch between it and Fahrenheit.

    At midnight the days should move one day forward. It works perfect with Crome 16, Firefox 3.6, Safari 5, Opera 11. But not in Explorer 9.

    The same thing happens if first loading the page with xml set to milan,italy. Then change the 'xml url' city to paris,france - move files to the server - and the Explorer is still showing milan,italy. Even though it should show paris,france.

    If having only one set of files and no possibility to change between F and C, it works in Explorer. Why not with switch button.

    It seems that Explorer doesn't contact the xml source after the first time. Once the data is loaded, it is there and even when refreshing, the browser seems to use the data in its memory and to ignore the refresh for xml feed.

    When 'double set of file page' in explorer is showing old data even when the php has a new 'xml url', a 'single set file page' in explorer gets the new 'xml url' data. Then after refreshing the 'double set file page' the correct material is shown, once the 'single set file page' has loaded it in the browser memory for the 'double set file page' to use.

  • #6
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,978
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    All of this indicates that IE is caching the results of the PHP page. Request that the browser does not by adding this to the top of the PHP:
    PHP Code:
    header("Cache-Control: no-cache, must-revalidate");
    header("Expires: Sat, 26 Jul 1997 05:00:00 GMT");
    header("Pragma: no-cache"); 
    If it works in all other browsers, then this issue is with IE, and not that of the code in use. If it were all browsers, and still persists with no-cache, then its cached at the ISP or router land, in which case there is little that can be done.

    I don't understand what you mean by 'double set of file page'? As with the Fahrenheit and Celsius, you do not need multiple pages, you just need to accept input from the user and determine which to show, and default to one or the other when nothing else is available (probably not required as the service this is coming from will do this themselves). This can be done using GET or POST.

  • #7
    New Coder
    Join Date
    Jul 2011
    Posts
    40
    Thanks
    16
    Thanked 0 Times in 0 Posts
    Hi,
    I'll try to be more clear this time.

    When a HTML page is having one AJAX call to a PHP file, and from the PHP is a link to a XSL - it works in all five browsers. In this case user is not able to choose between C and F.
    The structure is:
    HTML
    AJAX call to PHP to show C according to a XSL with C details



    When a HTML page has two AJAX calls (one for C info and one for F info), it works in Safari, Firefox, Chrome and in Opera, but not in Explorer. In this case user is able to choose between C and F.
    The structure is:
    HTML
    AJAX call to PHP to show C according to a XSL with C details
    AJAX call to PHP to show F according to a XSL with F details

    What makes me wonder is, that why Explorer is showing the data correctly when there is one AJAX call (no option to choose between C and F), which means that it is not caching the data. But when there are two AJAX calls (possibility to choose between the C and F), the data is not updating in Explorer.

    The headers with old date did not help the Explorer situation. The other browsers show correctly in every situation.

  • #8
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,978
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    Couldn't really tell you the cause. This is beyond the scope of PHP and is either an issue with the Javascript in use, or just for using IE (which has always sucked :P).
    Send your request for PHP with a simple query string. Take a random set of numbers or the milliseconds and simply request with a
    Code:
    var date = new DateTime();
    var request = "yourpage.php?t=" + date.getMilliseconds();
    Wait, this is the same page you are accessing right, not two separate PHP pages? If its too separate which are unique, then your problem will be the ajax.

  • Users who have thanked Fou-Lu for this post:

    JonesJ (01-07-2012)

  • #9
    New Coder
    Join Date
    Jul 2011
    Posts
    40
    Thanks
    16
    Thanked 0 Times in 0 Posts
    Works, the headers gave the solution after all.

  • #10
    New Coder
    Join Date
    Jul 2011
    Posts
    40
    Thanks
    16
    Thanked 0 Times in 0 Posts
    Hi,
    The code in the post #3 shows all the data the XML provides, which in this case is five day forecast. How to limit it to the middle three?

  • #11
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,978
    Thanks
    4
    Thanked 2,659 Times in 2,628 Posts
    Quote Originally Posted by JonesJ View Post
    Hi,
    The code in the post #3 shows all the data the XML provides, which in this case is five day forecast. How to limit it to the middle three?
    XSLT isn't really my thing, but you can try this:
    Code:
    <?xml version="1.0"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:php="http://php.net/xsl">
    
    <xsl:template match="data">
    <html>
    	<head><title>Weather</title></head>
    	<body>
    		<table border="1">
    			<tr>
    				<xsl:call-template name="showweather">
    					<xsl:with-param name="w" select="weather[2]|weather[3]|weather[4]" />
    				</xsl:call-template>
    			</tr>
    		</table>
    	</body>
    </html>
    </xsl:template>
    
    <xsl:template name="showweather">
    	<xsl:param name="w" />
    	<xsl:for-each select="$w">
    		<td>
    			<p><xsl:value-of select="php:function('dateToDayOfWeek', ./date)" /></p>
    			<p><xsl:apply-templates select="./weatherIconUrl" /></p>
    		</td>
    	</xsl:for-each>
    </xsl:template>
    
    <xsl:template match="weatherIconUrl">
    	<img>
    		<xsl:attribute name="src">
    		<xsl:value-of select="." />
    		</xsl:attribute>
    	</img>
    </xsl:template>
    
    </xsl:stylesheet>
    You may need to check with the XML guys for the proper way to mark this up.

  • Users who have thanked Fou-Lu for this post:

    JonesJ (01-10-2012)


  •  

    Tags for this Thread

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •