Current location: Hot Scripts Forums » Programming Languages » PHP » Reading XML


Reading XML

Reply
  #1 (permalink)  
Old 03-30-08, 09:39 PM
anupamsr's Avatar
anupamsr anupamsr is offline
Newbie Coder
 
Join Date: Feb 2004
Posts: 48
Thanks: 0
Thanked 0 Times in 0 Posts
Unhappy 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($parserXML_OPTION_TARGET_ENCODING"UTF-8");
xml_parser_set_option($parserXML_OPTION_CASE_FOLDINGtrue);

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($fp4096)) {
    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.
Reply With Quote
  #2 (permalink)  
Old 03-31-08, 11:03 PM
phpdoctor's Avatar
phpdoctor phpdoctor is offline
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'] = ;
            }

        
$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:
PHP Code:



include 'xml.class.php' // include the class file

$xml = new XF_Xml // create an instance of that class

echo '<pre>' ;
print_r($xml->xmlFileToArray('xml_file_name.xml')) ; // turn the xml file into an array and display it :) 
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
Reply With Quote
  #3 (permalink)  
Old 04-01-08, 05:45 AM
Jay6390's Avatar
Jay6390 Jay6390 is offline
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
__________________
Useful Tutorials
[ PHP Video-1-2-3 ] [ MySQL 1-2-3 ]
For any php function reference type

www.php.net/FunctionName
Reply With Quote
  #4 (permalink)  
Old 04-01-08, 09:22 AM
anupamsr's Avatar
anupamsr anupamsr is offline
Newbie Coder
 
Join Date: Feb 2004
Posts: 48
Thanks: 0
Thanked 0 Times in 0 Posts
But it still doesn't work:

Code:
Parse error: syntax error, unexpected T_STRING, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /home/walledga/public_html/xml.class.php on line 19
http://www.walledgardennearghat.com/a.php

Last edited by anupamsr; 04-01-08 at 09:26 AM.
Reply With Quote
  #5 (permalink)  
Old 04-01-08, 09:29 AM
Nico's Avatar
Nico Nico is offline
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 View Post
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.
Reply With Quote
  #6 (permalink)  
Old 04-01-08, 09:31 AM
Jay6390's Avatar
Jay6390 Jay6390 is offline
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 View Post
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
__________________
Useful Tutorials
[ PHP Video-1-2-3 ] [ MySQL 1-2-3 ]
For any php function reference type

www.php.net/FunctionName
Reply With Quote
  #7 (permalink)  
Old 04-01-08, 11:27 AM
anupamsr's Avatar
anupamsr anupamsr is offline
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...
Reply With Quote
  #8 (permalink)  
Old 04-01-08, 11:33 AM
Jay6390's Avatar
Jay6390 Jay6390 is offline
Code Master
 
Join Date: Apr 2007
Location: United Kingdom
Posts: 1,330
Thanks: 0
Thanked 0 Times in 0 Posts
Take a look at this

Jay
__________________
Useful Tutorials
[ PHP Video-1-2-3 ] [ MySQL 1-2-3 ]
For any php function reference type

www.php.net/FunctionName
Reply With Quote
  #9 (permalink)  
Old 04-01-08, 12:20 PM
anupamsr's Avatar
anupamsr anupamsr is offline
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/)
PHP Code:

  <?php
  $doc 
= new DOMDocument();
  
$doc->load'books.xml' );
  
  
$books $doc->getElementsByTagName"book" );
  foreach( 
$books as $book )
  {
  
$authors $book->getElementsByTagName"author" );
  
$author $authors->item(0)->nodeValue;
  
  
$publishers $book->getElementsByTagName"publisher" );
  
$publisher $publishers->item(0)->nodeValue;
  
  
$titles $book->getElementsByTagName"title" );
  
$title $titles->item(0)->nodeValue;
  
  echo 
"$title - $author - $publisher\n";
  }
  
?>
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
Reply With Quote
  #10 (permalink)  
Old 04-01-08, 12:34 PM
anupamsr's Avatar
anupamsr anupamsr is offline
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.
Reply With Quote
Reply

Bookmarks


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

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 Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Reading a Node from XML to VB.NET label MistyJoy Windows .NET Programming 2 07-16-09 12:38 AM
XML PHP MYSQL- Writing to a xml file punky79 PHP 8 05-18-09 04:21 AM
XML Reading infoscripts ASP 1 12-15-06 02:05 PM
reading a remote xml file into a variable bdee1 PHP 1 12-20-05 12:32 PM
XML (You'll groan while reading this) liljoeyjordison HTML/XHTML/XML 1 08-19-05 11:14 PM


All times are GMT -5. The time now is 07:39 AM.
vBulletin® Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.