PEAR is archived and read-only

This mirror preserves historical PEAR package releases and metadata so existing references remain available.

Home » XML » XML_Parser » Bug #5979

cdataHandler function called twice inside same tag

Details

Submitted2005-11-16 09:54 UTC
Frommartin dot ottenwaelter at free dot fr
StatusWont fix
PackageXML_Parser
PHP VersionIrrelevant
OSIrrelevant
Roadmaps(Not assigned)

Comments

[2005-11-16 09:54 UTC] martin dot ottenwaelter at free dot fr

Description:
------------
We expect the function cdataHandler to be called once
each time it encounters data between two XML tags. The
following example shows how cdataHandler is called twice
inside the same tag, confusing the programmer who wants
to capture once and only once data between two tags.

What is strange about this example is that the bug only
occurs for certain string and not for other. It might be
a string encoding problem as I am using UTF8.

Test script:
---------------
require_once 'XML/Parser.php';

class myParser extends XML_Parser {
function myParser() { parent::XML_Parser(); }

function startHandler($xp, $name, $attribs) {
printf('handle start tag: %s<br />', $name);
}
function endHandler($xp, $name) {
printf('handle end tag: %s<br />', $name);
}
function cdataHandler($xp, $cdata) {
printf('handle data: %s<br />', $cdata);
}
}

$p = &new myParser();

$result = $p->setInputString('<?xml version="1.0" encoding="utf-8"?><xml><tag>pré</tag></xml>');

$result = $p->parse();

Expected result:
----------------
Note that you MUST be using UTF8 encoding to see that
bug appear.

handle start tag: XML
handle start tag: TAG
handle data: pré
handle end tag: TAG
handle end tag: XML

Actual result:
--------------
handle start tag: XML
handle start tag: TAG
handle data: pr
handle data: é
handle end tag: TAG
handle end tag: XML

[2006-08-30 20:40 UTC] jmcgaw1 at gmail dot com

Created a "fix" for this bug. While running cdataHandler, simply record data by concatenating to global string. Then, when endHandler runs, write the global. This should solve your problem no matter how many times cdataHandle is called. By the way, this "quirk" should be better documented for XML_Parser, I thought I was going crazy when my strings were splitting. See code below:

Test script:
---------------
require_once 'XML/Parser.php';

class myParser extends XML_Parser {

var $tmpcdata;

function myParser() {
parent::XML_Parser();
$this->tmpcdata = "";
}

function startHandler($xp, $name, $attribs) {
printf('handle start tag: %s<br />', $name);
}

function endHandler($xp, $name) {
if (!empty($this->tmpcdata))
printf('handle data: %s<br />',$this->tmpcdata);
printf('handle end tag: %s<br />', $name);
$this->tmpcdata = "";
}

function cdataHandler($xp, $cdata) {
$this->tmpcdata = $this->tmpcdata . $cdata;
}
}

$p = &new myParser();
$result = $p->setInputString('<?xml version="1.0"
encoding="utf-8"?><xml><tag>pré</tag></xml>');
$result = $p->parse();