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
<URL>[b]synlig.adresse.net
<URI>[b][url]http://adresse-til.no/e
<Description><![CDATA[[b]Beskrivelse
<Bid>0</Bid>
</Listing>
<Listing>
<Title><![CDATA[[b]Tittel2
<URL>[b]synlig.adresse2.net
<URI>[b][url]http://adresse-til2.no/e
<Description><![CDATA[[b]Beskrivelse2
<Bid>0</Bid>
</Listing>
</Listings>
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>
Thanks in advance!
[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]
And what if I'm running PHP 4.3.11?[/QUOTE]
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.
[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]
[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]
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.
[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]
[code=php]
if(!$text)
{
die("ERROR: Unable to read file");
}
echo "DEBUG:<br>".html_entities($text);
[/code]
[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]
[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]
0.1.9 — BETA 5.18