/    Sign up×
Community /Pin to ProfileBookmark

XML to HTML via PHP

I’d really appreciate some help to exctract XML content to HTML via PHP. I’ve ordered a book on PHP, but I wouldn’t have it for a couple of weeks and I need this ready ASAP.

Here’s the external XML file:

[quote=”XML fila”]

<?xml version=”1.0″ encoding=”ISO-8859-1″?>
<Listings>
<Count>2</Count>
<Listing>
<Title><![CDATA[[b]Tittel[/b]]]></Title>
<URL>[b]synlig.adresse.net[/b]</URL>
<URI>[b][url]http://adresse-til.no/e[/url][/b]</URI>
<Description><![CDATA[[b]Beskrivelse[/b]]]></Description>
<Bid>0</Bid>
</Listing>
<Listing>
<Title><![CDATA[[b]Tittel2[/b]]]></Title>
<URL>[b]synlig.adresse2.net[/b]</URL>
<URI>[b][url]http://adresse-til2.no/e[/url][/b]</URI>
<Description><![CDATA[[b]Beskrivelse2[/b]]]></Description>
<Bid>0</Bid>
</Listing>
</Listings>

[/quote]

And here’s what I like to output:

[code]<a href=”http://adresse-til.no/e” title=”Tittel”><h3>Tittel</strong>
<p>Beskrivelse</p></a>
<small><a href=”http://adresse-til.no/e title=”Tittel”>synlig.adresse.net</a></small>

<a href=”http://adresse-til2.no/e” title=”Tittel2″><h3>Tittel2</strong>
<p>Beskrivelse2</p></a>
<small><a href=”http://adresse-til2.no/e title=”Tittel2″>synlig.adresse2.net</a></small>[/code]

Thanks in advance!

to post a comment
PHP

18 Comments(s)

Copy linkTweet thisAlerts:
@chazzyFeb 17.2006 — You don't need PHP to do this, you should be using XSLT.
Copy linkTweet thisAlerts:
@NogDogFeb 17.2006 — If you're running PHP5:
[code=php]
<?php
if (file_exists('sample.xml'))
{
$xml = simplexml_load_file('sample.xml');
foreach($xml->Listing as $val)
{
echo <<<XML
<p><a href="{$val->URI}" title="{$val->Title}"><strong>{$val->Title}</strong>
{$val->Description}</a><span style="font-size: small">
<a href="{$val->URI}" title="{$val->Title}">{$val->URL}</a></span>
XML;
}
}
else
{
exit('Failed to open test.xml.');
}
?>
[/code]

(Note: I altered the HTML markup a bit so that it might actually have a chance of validating.)
Copy linkTweet thisAlerts:
@MoldarinauthorFeb 17.2006 — And what if I'm running PHP 4.3.11?
Copy linkTweet thisAlerts:
@chazzyFeb 17.2006 — And what if I'm running PHP 4.3.11?[/QUOTE]

I would really recommend you to use an XML style sheet (XSLT) to just style it. no need for a server side language to parse this into your text.
Copy linkTweet thisAlerts:
@MoldarinauthorFeb 17.2006 — How can I do this?

The XML file is external and I cannot modify it.

I thougt using PHP vould be the easyiest way of doing this?
Copy linkTweet thisAlerts:
@the_treeFeb 17.2006 — If you can't edit the XML file then I'm afraid XSLT is out of the question, you can still use PHP 4.3, it would just be trickier.

http://uk2.php.net/domxml
Copy linkTweet thisAlerts:
@chazzyFeb 17.2006 — well, using DOM manipulation you can add the stylesheet to doc when you call it.
Copy linkTweet thisAlerts:
@bokehFeb 17.2006 — you can still use PHP 4.3, it would just be trickier.[/QUOTE]It is really pretty simple, if not a bit fiddley. All you need to do is build a stack. Pass through the XML string and work on the data. Everytime a new tag opens put it on the top of the stack, when the tag closes take it off the stack. That way you keep track of where you are within the document tree. If you come across a closing tag that doesn't match the opening tag on the top of the stack the XML is not well formed.
Copy linkTweet thisAlerts:
@MoldarinauthorFeb 17.2006 — Anyhow... I can't PHP just yet, so could anyone please help me with the code?

And I know about the validation part. I just figured I'd be able to edit it myself once I got it working...
Copy linkTweet thisAlerts:
@bokehFeb 17.2006 — A quick search found this:[code=php]<?php

$xmlFile = 'test.xml';

echo'<pre>';
print_r(xmlFileToArray($xmlFile));
echo'</pre>';



// {{{ toString()
/**
* This method converts a file to a string. It returns an Error object if it is unable to open the file.
*
* @param fileName String. The name of the file to convert.
*
* @return String
* @author simgar
*/

function & toString( $fileName )
{
if ($content_array = file($fileName))
{
return implode("", $content_array);
}
else
{
// Error
return false;
}
}
// }}}

// {{{ xmlFileToArray()
/**
* This static method converts an xml file to an associative array
* duplicating the xml file structure.
*
* @param $fileName. String. The name of the xml file to convert.
* This method returns an Error object if this file does not
* exist or is invalid.
* @param $includeTopTag. booleal. Whether or not the topmost xml tag
* should be included in the array. The default value for this is false.
* @param $lowerCaseTags. boolean. Whether or not tags should be
* set to lower case. Default value for this parameter is true.
* @access public static
* @return Associative Array
* @author Jason Read <[email protected]>
*/
function & xmlFileToArray($fileName, $includeTopTag = false, $lowerCaseTags = true)
{
// Definition file not found
if (!file_exists($fileName))
{
// Error
return false;
}
$p = xml_parser_create();
xml_parse_into_struct($p,toString($fileName),$vals,$index);
xml_parser_free($p);
$xml = array();
$levels = array();
$multipleData = array();
$prevTag = "";
$currTag = "";
$topTag = false;
foreach ($vals as $val)
{
// Open tag
if ($val["type"] == "open")
{
if (!_xmlFileToArrayOpen($topTag, $includeTopTag, $val, $lowerCaseTags,
$levels, $prevTag, $multipleData, $xml))
{
continue;
}
}
// Close tag
else if ($val["type"] == "close")
{
if (!_xmlFileToArrayClose($topTag, $includeTopTag, $val, $lowerCaseTags,
$levels, $prevTag, $multipleData, $xml))
{
continue;
}
}
// Data tag
else if ($val["type"] == "complete" && isset($val["value"]))
{
$loc =& $xml;
foreach ($levels as $level)
{
$temp =& $loc[str_replace(":arr#", "", $level)];
$loc =& $temp;
}
$tag = $val["tag"];
if ($lowerCaseTags)
{
$tag = strtolower($val["tag"]);
}
$loc[$tag] = str_replace("\n", "n", $val["value"]);
}
// Tag without data
else if ($val["type"] == "complete")
{
_xmlFileToArrayOpen($topTag, $includeTopTag, $val, $lowerCaseTags,
$levels, $prevTag, $multipleData, $xml);
_xmlFileToArrayClose($topTag, $includeTopTag, $val, $lowerCaseTags,
$levels, $prevTag, $multipleData, $xml);
}
}
return $xml;
}
// }}}

// {{{ _xmlFileToArrayOpen()
/**
* Private support function for xmlFileToArray. Handles an xml OPEN tag.
*
* @param $topTag. String. xmlFileToArray topTag variable
* @param $includeTopTag. boolean. xmlFileToArray includeTopTag variable
* @param $val. String[]. xmlFileToArray val variable
* @param $currTag. String. xmlFileToArray currTag variable
* @param $lowerCaseTags. boolean. xmlFileToArray lowerCaseTags variable
* @param $levels. String[]. xmlFileToArray levels variable
* @param $prevTag. String. xmlFileToArray prevTag variable
* @param $multipleData. boolean. xmlFileToArray multipleData variable
* @param $xml. String[]. xmlFileToArray xml variable
* @access private static
* @return boolean
* @author Jason Read <[email protected]>
*/
function _xmlFileToArrayOpen(& $topTag, & $includeTopTag, & $val, & $lowerCaseTags,
& $levels, & $prevTag, & $multipleData, & $xml)
{
// don't include top tag
if (!$topTag && !$includeTopTag)
{
$topTag = $val["tag"];
return false;
}
$currTag = $val["tag"];
if ($lowerCaseTags)
{
$currTag = strtolower($val["tag"]);
}
$levels[] = $currTag;

// Multiple items w/ same name. Convert to array.
if ($prevTag === $currTag)
{
if (!array_key_exists($currTag, $multipleData) ||
!$multipleData[$currTag]["multiple"])
{
$loc =& $xml;
foreach ($levels as $level)
{
$temp =& $loc[$level];
$loc =& $temp;
}
$loc = array($loc);
$multipleData[$currTag]["multiple"] = true;
$multipleData[$currTag]["multiple_count"] = 0;
}
$multipleData[$currTag]["popped"] = false;
$levels[] = ":arr#" . ++$multipleData[$currTag]["multiple_count"];
}
else
{
$multipleData[$currTag]["multiple"] = false;
}

// Add attributes array
if (array_key_exists("attributes", $val))
{
$loc =& $xml;
foreach ($levels as $level)
{
$temp =& $loc[str_replace(":arr#", "", $level)];
$loc =& $temp;
}
$keys = array_keys($val["attributes"]);
foreach ($keys as $key)
{
$tag = $key;
if ($lowerCaseTags)
{
$tag = strtolower($tag);
}
$loc["attributes"][$tag] = & $val["attributes"][$key];
}
}
return true;
}
// }}}

// {{{ _xmlFileToArrayClose()
/**
* Private support function for xmlFileToArray. Handles an xml OPEN tag.
*
* @param $topTag. String. xmlFileToArray topTag variable
* @param $includeTopTag. boolean. xmlFileToArray includeTopTag variable
* @param $val. String[]. xmlFileToArray val variable
* @param $currTag. String. xmlFileToArray currTag variable
* @param $lowerCaseTags. boolean. xmlFileToArray lowerCaseTags variable
* @param $levels. String[]. xmlFileToArray levels variable
* @param $prevTag. String. xmlFileToArray prevTag variable
* @param $multipleData. boolean. xmlFileToArray multipleData variable
* @param $xml. String[]. xmlFileToArray xml variable
* @access private static
* @return boolean
* @author Jason Read <[email protected]>
*/
function _xmlFileToArrayClose(& $topTag, & $includeTopTag, & $val, & $lowerCaseTags,
& $levels, & $prevTag, & $multipleData, & $xml)
{
// don't include top tag
if ($topTag && !$includeTopTag && $val["tag"] == $topTag)
{
return false;
}
if ($multipleData[$currTag]["multiple"])
{
$tkeys = array_reverse(array_keys($multipleData));
foreach ($tkeys as $tkey)
{
if ($multipleData[$tkey]["multiple"] && !$multipleData[$tkey]["popped"])
{
array_pop($levels);
$multipleData[$tkey]["popped"] = true;
break;
}
else if (!$multipleData[$tkey]["multiple"])
{
break;
}
}
}
$prevTag = array_pop($levels);
if (strpos($prevTag, "arr#"))
{
$prevTag = array_pop($levels);
}
return true;
}
// }}}
?> [/code]
Copy linkTweet thisAlerts:
@NogDogFeb 17.2006 — [code=php]
// read xml file into string
$text = file_get_contents("sample.xml");

// parse the xml into structure
$p = xml_parser_create();
xml_parser_set_option($p, XML_OPTION_CASE_FOLDING, 0);
xml_parse_into_struct($p, $text, $vals, $index);
xml_parser_free($p);

// read data of interest from structure into array:
for($i=0; $i<$index['Listings'][1]; $i++)
{
foreach(array('Title', 'URL', 'URI', 'Description', 'Bid') as $key)
{
$data[$i][$key] = $vals[$index[$key][$i]]['value'];
}
}

// output HTML:
foreach($data as $val)
{
echo <<<XML
<p><a href="{$val['URI']}" title="{$val['Title']}"><strong>{$val['Title']}</strong>
{$val['Description']}</a><span style="font-size: small">
<a href="{$val['URI']}" title="{$val['Title']}">{$val['URL']}</a></span>
XML;
}
[/code]
Copy linkTweet thisAlerts:
@SpectreReturnsFeb 17.2006 — bokeh, are those ampersands I see before the functions? What version of PHP is that for, 3?
Copy linkTweet thisAlerts:
@bokehFeb 17.2006 — bokeh, are those ampersands I see before the functions? What version of PHP is that for, 3?[/QUOTE]I'm not sure. I just copied it from a tutorial, gave it a quick run to make sure it worked and then posted it here.
Copy linkTweet thisAlerts:
@MoldarinauthorFeb 17.2006 — I really can't figure this out. Shouldn't this work just fine?
[code=php]<?php
// read xml file into string
$text = file_get_contents("http://www.searchfeed.com/rd/feed/XMLFeed.jsp?trackID=N5757523274&pID=49403&cat=blog&nl=5&page=1&ip=$REMOTE_ADDR");

// parse the xml into structure
$p = xml_parser_create();
xml_parser_set_option($p, XML_OPTION_CASE_FOLDING, 0);
xml_parse_into_struct($p, $text, $vals, $index);
xml_parser_free($p);

// read data of interest from structure into array:
for($i=0; $i<$index['Listings'][1]; $i++)
{
foreach(array('Title', 'URL', 'URI', 'Description', 'Bid') as $key)
{
$data[$i][$key] = $vals[$index[$key][$i]]['value'];
}
}

// output HTML:
foreach($data as $val)
{
echo <<<XML
<h3><a href="{$val['URI']}" title="{$val['Title']}">{$val['Title']}</a></h3>
<p>{$val['Description']}</p>
<a href="{$val['URI']}" title="{$val['Title']}"><small>{$val['URL']}</small></a>
XML;
}
?>[/code]


? Checked with Amazon by the way and they say I'll have my PHP book within four weeks [SIZE=1](shipped to Norway - no, Norway's not the capitol of Denmark nor Sweeden and we don't have polar bears in the steets either)[/SIZE].
Copy linkTweet thisAlerts:
@NogDogFeb 17.2006 — After the file_get_contents line, try doing the following to make sure you got the data:
[code=php]
if(!$text)
{
die("ERROR: Unable to read file");
}
echo "DEBUG:<br>".html_entities($text);
[/code]
Copy linkTweet thisAlerts:
@MoldarinauthorFeb 17.2006 — [b]Parse error[/b]: parse error, unexpected '<' in [b]public_html/test.php[/b] on line [b]9[/b]

[code=php]<?php

// read xml file into string
$text = file_get_contents("http://www.searchfeed.com/rd/feed/XMLFeed.jsp?trackID=N5757523274&pID=49403&cat=blog&nl=5&page=1&ip=$REMOTE_ADDR");


if(!$text) {
die("ERROR: Unable to read file");
}
echo "DEBUG:<br>$text";

// parse the xml into structure
$p = xml_parser_create();
xml_parser_set_option($p, XML_OPTION_CASE_FOLDING, 0);
xml_parse_into_struct($p, $text, $vals, $index);
xml_parser_free($p);

// read data of interest from structure into array:
for($i=0; $i<$index['Listings'][1]; $i++)
{
foreach(array('Title', 'URL', 'URI', 'Description', 'Bid') as $key)
{
$data[$i][$key] = $vals[$index[$key][$i]]['value'];
}
}

// output HTML:
foreach($data as $val)
{
echo <<<XML
<h3><a href="{$val['URI']}" title="{$val['Title']}">{$val['Title']}</a></h3>
<p>{$val['Description']}</p>
<a href="{$val['URI']}" title="{$val['Title']}"><small>{$val['URL']}</small></a>
XML;
}
?>[/code]
Copy linkTweet thisAlerts:
@NogDogFeb 18.2006 — I just ran this from my PC and it worked fine:
[code=php]
<?php

// read xml file into string
$text = file_get_contents("http://www.searchfeed.com/rd/feed/XMLFeed.jsp?trackID=N5757523274&pID=49403&cat=blog&nl=5&page=1&ip=$REMOTE_ADDR");

if(!$text) {
die("ERROR: Unable to read file");
}

// parse the xml into structure
$p = xml_parser_create();
xml_parser_set_option($p, XML_OPTION_CASE_FOLDING, 0);
xml_parse_into_struct($p, $text, $vals, $index);
xml_parser_free($p);

// read data of interest from structure into array:
for($i=0; $i<$index['Listings'][1]; $i++)
{
foreach(array('Title', 'URL', 'URI', 'Description', 'Bid') as $key)
{
$data[$i][$key] = $vals[$index[$key][$i]]['value'];
}
}

// output HTML:
foreach($data as $val)
{
echo <<<XML
<h3><a href="{$val['URI']}" title="{$val['Title']}">{$val['Title']}</a></h3>
<p>{$val['Description']}</p>
<a href="{$val['URI']}" title="{$val['Title']}"><small>{$val['URL']}</small></a>
XML;
}
?>
[/code]
Copy linkTweet thisAlerts:
@MoldarinauthorFeb 18.2006 — My web server (PHP 4.3.11) just show a blank page when I tried to use your code. -the document was empty.

Running it localy on Mac OS 10.4.5 just showed everything in the PHP as the document is written after [i]echo <<<XML[/i].
×

Success!

Help @Moldarin spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.18,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,

tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,
)...