Go Back   CodingForums.com > :: Server side development > PHP

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 12-29-2011, 07:29 PM   PM User | #1
JonesJ
New Coder

 
Join Date: Jul 2011
Posts: 36
Thanks: 15
Thanked 0 Times in 0 Posts
JonesJ is an unknown quantity at this point
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..
JonesJ is offline   Reply With Quote
Old 12-29-2011, 09:13 PM   PM User | #2
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,650
Thanks: 4
Thanked 2,451 Times in 2,420 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
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.
Fou-Lu is offline   Reply With Quote
Users who have thanked Fou-Lu for this post:
JonesJ (12-30-2011)
Old 12-30-2011, 02:29 PM   PM User | #3
JonesJ
New Coder

 
Join Date: Jul 2011
Posts: 36
Thanks: 15
Thanked 0 Times in 0 Posts
JonesJ is an unknown quantity at this point
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
JonesJ is offline   Reply With Quote
Old 12-30-2011, 03:44 PM   PM User | #4
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,650
Thanks: 4
Thanked 2,451 Times in 2,420 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
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>
Fou-Lu is offline   Reply With Quote
Users who have thanked Fou-Lu for this post:
JonesJ (12-30-2011)
Old 01-05-2012, 06:16 PM   PM User | #5
JonesJ
New Coder

 
Join Date: Jul 2011
Posts: 36
Thanks: 15
Thanked 0 Times in 0 Posts
JonesJ is an unknown quantity at this point
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.
JonesJ is offline   Reply With Quote
Old 01-05-2012, 06:45 PM   PM User | #6
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,650
Thanks: 4
Thanked 2,451 Times in 2,420 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
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.
Fou-Lu is offline   Reply With Quote
Old 01-05-2012, 10:46 PM   PM User | #7
JonesJ
New Coder

 
Join Date: Jul 2011
Posts: 36
Thanks: 15
Thanked 0 Times in 0 Posts
JonesJ is an unknown quantity at this point
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.
JonesJ is offline   Reply With Quote
Old 01-06-2012, 12:02 AM   PM User | #8
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,650
Thanks: 4
Thanked 2,451 Times in 2,420 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
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.
Fou-Lu is offline   Reply With Quote
Users who have thanked Fou-Lu for this post:
JonesJ (01-07-2012)
Old 01-07-2012, 04:02 PM   PM User | #9
JonesJ
New Coder

 
Join Date: Jul 2011
Posts: 36
Thanks: 15
Thanked 0 Times in 0 Posts
JonesJ is an unknown quantity at this point
Works, the headers gave the solution after all.
JonesJ is offline   Reply With Quote
Old 01-09-2012, 11:49 PM   PM User | #10
JonesJ
New Coder

 
Join Date: Jul 2011
Posts: 36
Thanks: 15
Thanked 0 Times in 0 Posts
JonesJ is an unknown quantity at this point
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?
JonesJ is offline   Reply With Quote
Old 01-10-2012, 01:50 PM   PM User | #11
Fou-Lu
God Emperor


 
Fou-Lu's Avatar
 
Join Date: Sep 2002
Location: Saskatoon, Saskatchewan
Posts: 15,650
Thanks: 4
Thanked 2,451 Times in 2,420 Posts
Fou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to allFou-Lu is a name known to all
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.
Fou-Lu is offline   Reply With Quote
Users who have thanked Fou-Lu for this post:
JonesJ (01-10-2012)
Reply

Bookmarks

Tags
php, xslt

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 07:17 PM.


Advertisement
Log in to turn off these ads.