我注意到在下面的例子中,以及我在这个网站上看到的关于在 HTML 中查看 XML 的所有例子中,自闭合标签(如 <br />)的外观没有保留。解析器无法区分 <tag /> 和 <tag></tag>,如果您的开始和结束元素函数类似于这些例子,那么这两个实例都将输出一个单独的开始和结束标签。我需要保留自闭合标签,而且花了一段时间才弄明白这个解决方法。希望这能帮到其他人...
开始标签保持打开状态,然后由它的第一个子节点(下一个开始标签或它的结束标签)完成。结束标签将使用 “ />” 或 </tag> 完成,具体取决于解析数据中开始标签和结束标签之间的字节数。
<?php
$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) 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}"); }
function endElement($parser, $name)
{
global $first_child, $start_byte;
$byte=xml_get_current_byte_index ($parser);
if($byte-$start_byte>2){ if($first_child) echo "><br />";
echo htmlentities("</{$name}>")."<br />"; }else
echo " /><br />"; $first_child=false;
}
function characterData($parser, $data)
{
global $first_child;
if($first_child) 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);
?>