php实现的xml文件分析类。
代码:
复制代码 代码示例:
<?php
/**
* xml节点类
*/
class Node {
var $name;
var $attributes;
var $ancestors = "/"
var $data;
var $type;
function Node($tree) {
$this->name = array_pop($tree);
$this->ancestors .= implode("/", $tree);
}
function add_data($value) {
$this->data .= ' '.$value;
}
function get_type() {
if (strlen($this->data) > 0) {
return "with CDATA"
} else {
return "without CDATA"
}
}
function level() {
if ($this->ancestors == "/") return 0;
if (preg_match_all("/(/{1})/", $this->ancestors, $result,PREG_PATTERN_ORDER)) {
return (count($result[0]));
} else {
return 0;
}
}
function has_attributes() {
return (is_array($this->attributes));
}
function print_name() {
return "$this->name";
}
function is_child($node) {
$result = preg_match("/^$ancestors/", $node->ancestors, $match);
if ($node->ancestors == $this->ancestors) $result = false;
return $result;
}
}
/**
* xml分析类
*/
class XML {
var $file;
var $tree = array();
var $nodes = array();
var $PIs;
var $format_body = "font-family:Verdana;font-size:10pt;"
var $format_bracket = "color:blue;"
var $format_element = "font-family:Verdana;font-weight:bold;font-size:10pt;"
var $format_attribute = "font-family:Courier;font-size:10pt;"
var $format_data = "font-size:12pt;"
var $format_attribute_name = "color:#444444;"
var $format_attribute_value = "font-family:Courier;font-size:10pt;color:red;"
var $format_blanks = " "
function XML($filename) {
$this->file = $filename;
$xml_parser = xml_parser_create();
xml_set_object($xml_parser,&$this);
xml_set_element_handler($xml_parser, "startElement", "endElement");
xml_set_character_data_handler($xml_parser, "characterData");
xml_set_processing_instruction_handler ($xml_parser, "process_instruction");
# Why should one want to use case-folding with XML? XML is case-sensitiv, I think this is nonsense
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, false);
if (!($fp = @fopen($this->file, "r"))) {
die(print("Couldn't open file: $this->filen"));
}
while ($data = fread($fp, 4096)) {
if (!xml_parse($xml_parser, $data, feof($fp))) {
die(sprintf("XML error: %s at line %dn",
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser)));
}
}
}
function startElement($parser, $name, $attribs) {
# Adding the additional element to the tree, including attributes
$this->tree[] = $name;
$node = new Node($this->tree);
while (list($k, $v) = each($attribs)) {
$node->attributes[$k] = $v;
}
$this->nodes[] = $node;
}
function endElement($parser, $name) {
# Adding a new element, describing the end of the tag
# But only, if the Tag has CDATA in it!
# Check
if (count($this->nodes) >= 1) {
$prev_node = $this->nodes[count($this->nodes)-1];
if (strlen($prev_node->data) > 0 || $prev_node->name != $name) {
$this->tree[count($this->tree)-1] = "/".$this->tree[count($this->tree)-1];
$this->nodes[] = new Node($this->tree, NULL);
} else {
# Adding a slash to the end of the prev_node
$prev_node->name = $prev_node->name."/"
$this->nodes[count($this->nodes)-1]->name = $this->nodes[count($this->nodes)-1]->name."/"
}
}
# Removing the element from the tree
array_pop($this->tree);
}
function characterData($parser, $data) {
$data = ltrim($data);
if ($data != "") $this->nodes[count($this->nodes)-1]->add_data($data);
}
function process_instruction($parser, $target, $data) {
if (preg_match("/xml:stylesheet/", $target, $match) && preg_match("/type="text/xsl"/", $data, $match)) {
preg_match("/href="(.+)"/i", $data, $this->PIs);
# print "<b>found xls pi: $PIs[1]</b><br>n"
}
}
function print_nodes() {
# Printing the header
print "<html><head><title>".$this->nodes[0]->name."</title></head>"
print "<body style="".$this->format_body."">n"
# Printing the XML Data
for ($i = 0; $i < count($this->nodes); $i++) {
$node = $this->nodes[$i];
# Checking: Empty element
if ($node->name[strlen($node->name)-1] == "/") {
$end_char = "/"
$node->name = substr($node->name, 0, strlen($node->name)-1);
} else {
$end_char = ""
}
# Writing whitespaces, but only if it's _no_ closing element that follows
# directly on it's opening element
if (!("/".$this->nodes[$i-1]->name == $node->name)) {
for ($j = 0; $j < $node->level(); $j++) echo $this->format_blanks;
}
echo "<span style="".$this->format_bracket.""><</span><span style="".$this->format_element."">".$node->name."</span>"
if ($node->has_attributes()) {
$keys = array_keys($node->attributes);
for ($j = 0; $j < count($keys); $j++) {
printf(" <span style="%s">%s="</span><span style="%s">%s</span><span style="%s">"</span>", $this->format_attribute_name, $keys[$j], $this->format_attribute_value, $node->attributes[$keys[$j]], $this->format_attribute_name);
}
echo " "
}
echo "<span style="".$this->format_element."">$end_char</span><span style="".$this->format_bracket."">></span>"
if (strlen($node->data) > 0) echo "<span style="".$this->format_data."">".ltrim($node->data)."</span>"
else echo "<br>n"
}
# Printing the footer
print "</body></html>n"
}
}
调用示例:
复制代码 代码示例:
<?php
$xml = new XML('artikel.xml');
$xml->print_nodes();