php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #19862 online documentation is bugged...
Submitted: 2002-10-11 08:01 UTC Modified: 2003-01-25 13:08 UTC
From: priit at ww dot ee Assigned:
Status: Not a bug Package: Documentation problem
PHP Version: 4.2.3 OS: any
Private report: No CVE-ID: None
 [2002-10-11 08:01 UTC] priit at ww dot ee
URL: http://www.php.net/manual/en/ref.xml.php

how the files are opened is not the correct way or the input/output may get mixed up or truncated on same cases...

I mean ... you should not open files in blocks, but whole file ... I copy pasted your example to my code and when some block (of those 4096 bytes) end and next blocks start value somehow happened to be in the middle XML value, then the value was truncated or cutted half in output. anyway the input (cycle) should be in one piece (whole file at once) or row by row, not by constant number of bytes.



Example 1. (your version)

$file = "data.xml";
$depth = array();

function startElement($parser, $name, $attrs) {
    global $depth;
    for ($i = 0; $i < $depth[$parser]; $i++) {
        print "  ";
    }
    print "$name\n";
    $depth[$parser]++;
}

function endElement($parser, $name) {
    global $depth;
    $depth[$parser]--;
}

$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startElement", "endElement");
if (!($fp = fopen($file, "r"))) {
    die("could not open XML input");
}

while ($data = fread($fp, 4096)) {
    if (!xml_parse($xml_parser, $data, feof($fp))) {
        die(sprintf("XML error: %s at line %d",
                    xml_error_string(xml_get_error_code($xml_parser)),
                    xml_get_current_line_number($xml_parser)));
    }
}
xml_parser_free($xml_parser);




BUT THIS SHOULD BE (my version):

Example 1.

$file = "data.xml";
$depth = array();

function startElement($parser, $name, $attrs) {
    global $depth;
    for ($i = 0; $i < $depth[$parser]; $i++) {
        print "  ";
    }
    print "$name\n";
    $depth[$parser]++;
}

function endElement($parser, $name) {
    global $depth;
    $depth[$parser]--;
}

$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startElement", "endElement");
if (!($fp = fopen($file, "r"))) {
    die("could not open XML input");
}

$data = fread($fp, filesize($file)));
if (!xml_parse($xml_parser, $data, feof($fp)))
{
die(sprintf("XML error: %s at line %d",
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser)));
}

xml_parser_free($xml_parser);

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-10-11 08:54 UTC] msopacua@php.net
Expat is a SAX parser. It can handle blocks (or streams as they're preferred to be called these days) and doesn't care whether a document is valid or even when it is a document.

The point of using a stream-based parser, is that you're not required to open up files entirely (in fact - your input can be a socket).

Allthough the manual example dies, as soon as a parser error is detected, one can actually retrieve the linenumber of the error, store everything from that line on in a buffer, process the lines before that and retrieve the next block, appending it to the buffer.

So I agree, the example is not very useful in some cases, but not for your reasoning.
 [2003-01-25 13:08 UTC] hholzgra@php.net
see http://php.net/xml_parse :

[...]
data

    Chunk of data to parse. A document may be parsed piece-wise by calling xml_parse() several times with new data, as long as the is_final parameter is set and TRUE when the last data is parsed. 

is_final (optional)

    If set and TRUE, data is the last piece of data sent in this parse. 
[...]

it is totaly valid to split data chunks wherever you want, 
you may even feed xml_parse() character by character.

the manual example will not only work for local files but also for e.g. http: remote streams where you can't get the input size in advance, and for any kind of non-blocking stream where fread() may return less than the requested number of bytes even if EOF is not yet reached
 
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri May 24 13:01:31 2024 UTC