note 55360 added to function.xml-set-element-handler
| From: | ibjoel at hotmail dot com | Date: | Mon, 01 Aug 2005 10:49:29 +0000 |
| Subject: | note 55360 added to function.xml-set-element-handler | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-92859@lists.php.net to get a copy of this message | ||
I noticed that in the example below, and all the examples I've seen on this site for viewing
xml in html, the look of self closing tags such as <br /> are not preserved. The parser cannot
distinguish between <tag /> and <tag></tag>, and if your start and end element
functions are like these examples, both instances will be output with both an indvidual start and
end tag. I needed to preserve self-closing tags and it took me a while to figure out this work
around. Hope this helps someone...
The start tag is left open, and then completed by it's first child, the next start tag or its
end tag. The end tag will complete with " />", or </tag> depending on the number
of bytes between the start and end tags in the parsed data.
<?php
//$data=filepath or string
$data=<<<DATA
<normal_tag>
<self_close_tag />
data
<normal_tag>data
<self_close_tag attr="value" />
</normal_tag>
data
<normal_tag></normal_tag>
</normal_tag>
DATA;
function startElement($parser, $name, $attrs)
{
xml_set_character_data_handler($parser, "characterData");
global $first_child, $start_byte;
if($first_child) //close start tag if neccessary
echo "><br />";
$first_child=true;
$start_byte=xml_get_current_byte_index ($parser);
if(count($attrs)>=1){
foreach($attrs as $x=>$y){
$attr_string .= " $x=\"$y\"";
}
}
echo htmlentities("<{$name}{$attr_string}"); //unclosed starttag
}
function endElement($parser, $name)
{
global $first_child, $start_byte;
$byte=xml_get_current_byte_index ($parser);
if($byte-$start_byte>2){ //if end tag is more than 2 bytes from start tag
if($first_child) //close start tag if neccessary
echo "><br />";
echo htmlentities("</{$name}>")."<br />";
//individual end tag
}else
echo " /><br />"; // self closing tag
$first_child=false;
}
function characterData($parser, $data)
{
global $first_child;
if($first_child) //if $data is first child, close start tag
echo "><br />";
if($data=trim($data))
echo "<font color='blue'>$data</font><br />";
$first_child=false;
}
function ParseData($data)
{
$xml_parser = xml_parser_create();
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_parser_set_option($xml_parser,XML_OPTION_CASE_FOLDING,0);
if(is_file($data))
{
if (!($fp = fopen($file, "r"))) {
die("could not open XML input");
}
while ($data = fread($fp, 4096)) {
if (!xml_parse($xml_parser, $data, feof($fp))) {
$error=xml_error_string(xml_get_error_code($xml_parser));
$line=xml_get_current_line_number($xml_parser);
die(sprintf("XML error: %s at line %d",$error,$line));
}
}
}else{
if (!xml_parse($xml_parser, $data, 1)) {
$error=xml_error_string(xml_get_error_code($xml_parser));
$line=xml_get_current_line_number($xml_parser);
die(sprintf("XML error: %s at line %d",$error,$line));
}
}
xml_parser_free($xml_parser);
}
ParseData($data);
?>
----
Submitter IP: 62.236.74.67
----
Manual Page -- http://www.php.net/manual/en/function.xml-set-element-handler.php
Edit -- http://master.php.net/manage/user-notes.php?action=edit+55360
Delete: added to the manual -- http://master.php.net/manage/user-notes.php?action=delete+55360&report=yes&reason=added+to+the+manual
Delete: bad code -- http://master.php.net/manage/user-notes.php?action=delete+55360&report=yes&reason=bad+code
Delete: spam -- http://master.php.net/manage/user-notes.php?action=delete+55360&report=yes&reason=spam
Delete: useless -- http://master.php.net/manage/user-notes.php?action=delete+55360&report=yes&reason=useless
Delete: non-english -- http://master.php.net/manage/user-notes.php?action=delete+55360&report=yes&reason=non-english
Delete: other reasons -- http://master.php.net/manage/user-notes.php?action=delete+55360&report=yes
Reject -- http://master.php.net/manage/user-notes.php?action=reject+55360&report=yes
Search -- http://master.php.net/manage/user-notes.php