Voting

: eight plus zero?
(Example: nine)

The Note You're Voting On

hendra_g at hotmail dot com
19 years ago
I ran into the same problem with 'ibjoel at hotmail dot com' in regards to self-closing tags, and found that the script that he/she wrote did not work as I expected.
I played around with some of php's functions and examples and compiled something, which may not be the neatest solution, but it works for the data that 'ibjoel at hotmail dot com' provided.
The data needs to be read from a file though, so the fp can be utilised. It still uses the xml_get_current_byte_index(resource parser) trick, but this time, I check for the last 2 character before the index and test if it's "/>".

<?php
/* myxmltest.xml:
<normal_tag>
<self_close_tag />
data
<normal_tag>data
<self_close_tag attr="value" />
</normal_tag>
data
<normal_tag></normal_tag>
</normal_tag>
*/

//## Global Variables ##//
$file = "myxmltest.xml";
$character_data_on = false;
$tag_complete = true;

function
startElement($parser, $name, $attrs)
{
global
$character_data_on;
global
$tag_complete;

echo
"&lt;<font color=\"#0000cc\">$name</font>";
//## Print the attributes ##//
if (sizeof($attrs)) {
while (list(
$k, $v) = each($attrs)) {
echo
" <font color=\"#009900\">$k</font>=\"<font
color=\"#990000\">
$v</font>\"";
}
}
//## Tag is still still incomplete,
//## will be completed at either endElement or characterData ##//
$tag_complete = false;
$character_data_on = false;
}

function
endElement($parser, $name)
{
global
$fp;
global
$character_data_on;
global
$tag_complete;

//#### Test for self-closing tag ####//
//## xml_get_current_byte_index(resource parser) when run in this
//## function, gives the index at (indicated by *):
//## for self closing tag: <br />*
//## for individual closing tag: <div>character data*</div>
//## So to test for self-closing tag, we can just test for the last 2
//## characters from the index
//###################################//

if (!$character_data_on) {
//## Record current fp position ##//
$temp_fp = ftell($fp);

//## Point fp to 2 bytes before the end element byte index ##//
$end_element_byte_index = xml_get_current_byte_index($parser);
fseek($fp,$end_element_byte_index-2);

//## Gets the last 2 characters before the end element byte index ##//
$validator = fgets($fp, 3);

//## Restore fp position ##//
fseek($fp,$temp_fp);

//## If the last 2 character is "/>" ##//
if ($validator=="/>") {
//// Complete the self-closing tag ////
echo " /&gt";
//// Otherwise it is an individual closing tag ////
} else echo "&gt&lt/<font color=\"#0000cc\">$name</font>&gt";
$tag_complete = true;
} else echo
"&lt/<font color=\"#0000cc\">$name</font>&gt";

$character_data_on = false;
}

function
characterData($parser, $data)
{
global
$character_data_on;
global
$tag_complete;

if ((!
$character_data_on)&&(!$tag_complete)) {
echo
"&gt";
$tag_complete = true;
}
echo
"<b>$data</b>";
$character_data_on = true;
}

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

echo
"<pre>";
while (
$file_content = fread($fp, 4096)) {
if (!
xml_parse($xml_parser, $file_content, 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)));
}
}
echo
"</pre>";
xml_parser_free($xml_parser);
?>

<< Back to user notes page

To Top