03-30-08, 09:39 PM
Newbie Coder
Join Date: Feb 2004
Posts: 48
Thanks: 0
Thanked 0 Times in 0 Posts
Reading XML
Hi! I have a XML file and I am trying to read it through PHP. Everything seems to be ok
except , not all of the text is presented. For example, if the entry is bla1 bla2 bla3, only "a2 bla3" is reported.
Here is the xml file:
http://www.walledgardennearghat.com/blog.xml
Here is the code to read it:
PHP Code:
<?php $file = 'blog.xml' ; putenv ( "TZ=Europe/London" ); $blogs = array(); $elem = null ; function startElement ( $parser , $name , $attrs ) { global $blogs , $elem ; if ( $name == 'BLOG' ) { $blogs []= array(); } $elem = $name ; } function endElement ( $parser , $name ) { global $elem ; $elem = null ; } function xml_escape ( $s ) { $result = '' ; $len = strlen ( $s ); for ( $i = 0 ; $i < $len ; $i ++) { if ( ord ( $s { $i }) > 127 ) { // skipping UTF-8 escape sequences requires a bit of work if (( ord ( $s { $i }) & 0xf0 ) == 0xf0 ) { $result .= $s { $i ++}; $result .= $s { $i ++}; $result .= $s { $i ++}; $result .= $s { $i }; } else if (( ord ( $s { $i }) & 0xe0 ) == 0xe0 ) { $result .= $s { $i ++}; $result .= $s { $i ++}; $result .= $s { $i }; } else if (( ord ( $s { $i }) & 0xc0 ) == 0xc0 ) { $result .= $s { $i ++}; $result .= $s { $i }; } } else { $result .= $s { $i }; } } return $result ; } function textData ( $parser , $text ) { global $blogs , $elem ; if ( $elem == 'TIME' || $elem == 'TITLE' || $elem == 'TEXT' ) { $blogs [ count ( $blogs ) - 1 ][ $elem ] = xml_escape ( $text ); } } $parser = xml_parser_create ( "UTF-8" ); xml_parser_set_option ( $parser , XML_OPTION_TARGET_ENCODING , "UTF-8" ); xml_parser_set_option ( $parser , XML_OPTION_CASE_FOLDING , true ); xml_set_element_handler ( $parser , 'startElement' , 'endElement' ); xml_set_character_data_handler ( $parser , 'textData' ); if (!( $fp = fopen ( $file , 'r' ))) { die( "\n<p>Couldn\'t open $file at " . date ( 'l dS \of F Y h:i:s A' ). "</p><p><strong>Please report this at webmaster@walledgardennearghat.com</strong></p>" ); } while( $data = fread ( $fp , 4096 )) { if (! xml_parse ( $parser , $data )) { die( sprintf ( "Error parsing <b>%s</b>: %s at line %d\n\n" , $file , xml_error_string ( xml_get_error_code ( $parser )), xml_get_current_line_number ( $parser ))); } } xml_parser_free ( $parser ); fclose ( $fp ); foreach( $blogs as $blog ) { echo "\t\t\t\t\t" . '<li><a href="#' . $blog [ 'TIME' ]. '">' . $blog [ 'TITLE' ]. '</a></li>' . "\n" ; } echo "\t\t\t\t</ol>\n" ; echo "\t\t\t</div>\n" ; echo "\t\t</div>\n" ; foreach( $blogs as $blog ) { echo "\t\t" . '<div class="title"><a name="' . $blog [ 'TIME' ]. '"></a><h3>' . $blog [ 'TITLE' ]. '</h3>' . date ( 'h:i a, j F Y' , $blog [ 'TIME' ]). '</div>' . "\n" ; echo "\t\t" . '<div class="textbody">' . "\n" ; echo "\t\t\t" . $blog [ 'TEXT' ]. "\n" ; echo "\t\t</div>\n" ; }
You can see the output at
http://www.walledgardennearghat.com/blog.php
Specifically,
http://www.walledgardennearghat.com/blog.php#1204845420
It is driving me crazy... I have generally no idea of XML or PHP, and my script has its roots in Google. So please reply in noob terms.
Last edited by anupamsr; 03-30-08 at 09:42 PM .
03-31-08, 11:03 PM
Code Guru
Join Date: Feb 2007
Location: New Zealand
Posts: 767
Thanks: 4
Thanked 2 Times in 2 Posts
Heres a xml class that i have:
PHP Code:
<?php
class XF_Xml
{
/**
* This static method converts an xml file to an associative array
* duplicating the xml file structure.
*
* @access public
* @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.
* @return Associative Array
*/
public function & xmlFileToArray ( $fileName , $includeTopTag = false , $lowerCaseTags = true )
{
// Definition file not found
if (! file_exists ( $fileName ))
{
return false ; // Error
}
$p = xml_parser_create () ;
xml_parse_into_struct ( $p , $this -> toString ( $fileName ), $vals , $index ) ;
xml_parser_free ( $p ) ;
$xml = array() ;
$levels = array() ;
$multipleData = array() ;
$prevTag = '' ;
$currTag = '' ;
$topTag = false ;
foreach ( $vals as $val )
{
if ( $val [ 'type' ] == 'open' ) // Open tag
{
if (! $this -> _xmlFileToArrayOpen ( $topTag , $includeTopTag , $val , $lowerCaseTags , $levels , $prevTag , $multipleData , $xml ))
{
continue ;
}
}
else if ( $val [ 'type' ] == 'close' ) // Close tag
{
if (! $this -> _xmlFileToArrayClose ( $topTag , $includeTopTag , $val , $lowerCaseTags , $levels , $prevTag , $multipleData , $xml ))
{
continue ;
}
}
else if ( $val [ 'type' ] == 'complete' && isset( $val [ 'value' ])) // Data tag
{
$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' ]);
}
else if ( $val [ 'type' ] == 'complete' ) // Tag without data
{
$this -> _xmlFileToArrayOpen ( $topTag , $includeTopTag , $val , $lowerCaseTags , $levels , $prevTag , $multipleData , $xml ) ;
$this -> _xmlFileToArrayClose ( $topTag , $includeTopTag , $val , $lowerCaseTags , $levels , $prevTag , $multipleData , $xml ) ;
}
}
return $xml ;
}
//--------------------------------------------------
/**
* Private support function for xmlFileToArray. Handles an xml OPEN tag.
*
* @access private
* @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
* @return boolean
*/
private 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 ;
}
//--------------------------------------------------
/**
* Private support function for xmlFileToArray. Handles an xml OPEN tag.
*
* @access private
* @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
* @return boolean
*/
private 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 ;
}
//--------------------------------------------------
/**
* 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
*/
private function & toString ( $fileName )
{
if ( $content_array = file ( $fileName ))
{
return implode ( '' , $content_array ) ;
}
else
{
return false ; // error
}
}
}
?>
Just copy that code and put it into a file called 'xml.class.php' (or something like that)
To use it you need to include and create a instance of that class:
I found the link where i first got this code:
http://www.codewalkers.com/c/a/Datab...-XML-To-Array/
You dont really need to understand how the code works (i havent even looked at it lol). As long it works hehe.
Any questions?
Hope that helps,
Lex
__________________
01010000 01001000 01010000
04-01-08, 05:45 AM
Code Master
Join Date: Apr 2007
Location: United Kingdom
Posts: 1,330
Thanks: 0
Thanked 0 Times in 0 Posts
Nice piece of code Lex. I'm just starting to look into XML parsing myself
*grabs code*
. i'll have to work out how this does what it does
04-01-08, 09:22 AM
Newbie Coder
Join Date: Feb 2004
Posts: 48
Thanks: 0
Thanked 0 Times in 0 Posts
Last edited by anupamsr; 04-01-08 at 09:26 AM .
04-01-08, 09:29 AM
Community Leader
Join Date: Sep 2005
Location: Spain
Posts: 8,075
Thanks: 11
Thanked 88 Times in 83 Posts
You're getting this error because you're using PHP 4, and Lex' code is for PHP 5.
Quote:
Originally Posted by
Jay6390
Nice piece of code Lex. I'm just starting to look into XML parsing myself
*grabs code*
. i'll have to work out how this does what it does
I would suggest taking a look at
SimpleXML , it's much easier and you don't have to carry this code around.
04-01-08, 09:31 AM
Code Master
Join Date: Apr 2007
Location: United Kingdom
Posts: 1,330
Thanks: 0
Thanked 0 Times in 0 Posts
Quote:
Originally Posted by
Nico
I would suggest taking a look at
SimpleXML , it's much easier and you don't have to carry this code around.
Nice link. Cheers Nico
04-01-08, 11:27 AM
Newbie Coder
Join Date: Feb 2004
Posts: 48
Thanks: 0
Thanked 0 Times in 0 Posts
Oh! Any code for PHP4? I am kinda stuck with it...
04-01-08, 11:33 AM
Code Master
Join Date: Apr 2007
Location: United Kingdom
Posts: 1,330
Thanks: 0
Thanked 0 Times in 0 Posts
04-01-08, 12:20 PM
Newbie Coder
Join Date: Feb 2004
Posts: 48
Thanks: 0
Thanked 0 Times in 0 Posts
I tried the use of DOM: (from
http://www.ibm.com/developerworks/library/os-xmldomphp/ )
I get this error:
Parse error : syntax error, unexpected T_OBJECT_OPERATOR in
/home/walledga/public_html/books.php on line
9
Now I have no idea
04-01-08, 12:34 PM
Newbie Coder
Join Date: Feb 2004
Posts: 48
Thanks: 0
Thanked 0 Times in 0 Posts
If you think this is a problem with php installation, please tell me.
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
Thread Tools
Display Modes
Linear Mode
Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off