Php xml Parser


 / Published in: PHP
 

  1. ************************************************************************
  2. Example:
  3. ************************************************************************
  4.  
  5.  
  6. $xml = new XML('artikel.xml');
  7. $xml->print_nodes();
  8.  
  9. ?>
  10.  
  11. ***********************************************************************
  12. Script
  13. ***********************************************************************
  14.  
  15.  
  16. <?php
  17.  
  18. # This script formats a xml file according to some rules. These rules
  19. # are processed in the function that xml_set_character_data_handler
  20. # defines. We have to remember, in which element we are, and furthermore,
  21. # which ancestor elements the current element has.
  22.  
  23. class Node {
  24. var $name;
  25. var $attributes;
  26. var $ancestors = "/"
  27. var $data;
  28. var $type;
  29.  
  30. function Node($tree) {
  31. $this->name = array_pop($tree);
  32. $this->ancestors .= implode("/", $tree);
  33. }
  34.  
  35. function add_data($value) {
  36. $this->data .= ' '.$value;
  37. }
  38.  
  39. function get_type() {
  40. if (strlen($this->data) > 0) {
  41. return "with CDATA"
  42. } else {
  43. return "without CDATA"
  44. }
  45. }
  46.  
  47. function level() {
  48. if ($this->ancestors == "/") return 0;
  49. if (preg_match_all("/(\/{1})/", $this->ancestors, $result,PREG_PATTERN_ORDER)) {
  50. return (count($result[0]));
  51. } else {
  52. return 0;
  53. }
  54. }
  55.  
  56. function has_attributes() {
  57. return (is_array($this->attributes));
  58. }
  59.  
  60. function print_name() {
  61. return "$this->name";
  62. }
  63.  
  64. function is_child($node) {
  65. $result = preg_match("/^$ancestors/", $node->ancestors, $match);
  66. if ($node->ancestors == $this->ancestors) $result = false;
  67. return $result;
  68. }
  69. }
  70.  
  71. class XML {
  72. var $file;
  73. var $tree = array();
  74. var $nodes = array();
  75. var $PIs;
  76. var $format_body = "font-family:Verdana;font-size:10pt;"
  77. var $format_bracket = "color:blue;"
  78. var $format_element = "font-family:Verdana;font-weight:bold;font-size:10pt;"
  79. var $format_attribute = "font-family:Courier;font-size:10pt;"
  80. var $format_data = "font-size:12pt;"
  81. var $format_attribute_name = "color:#444444;"
  82. var $format_attribute_value = "font-family:Courier;font-size:10pt;color:red;"
  83. var $format_blanks = "   "
  84.  
  85. function XML($filename) {
  86. $this->file = $filename;
  87. $xml_parser = xml_parser_create();
  88. xml_set_object($xml_parser,&$this);
  89. xml_set_element_handler($xml_parser, "startElement", "endElement");
  90. xml_set_character_data_handler($xml_parser, "characterData");
  91. xml_set_processing_instruction_handler ($xml_parser, "process_instruction");
  92. # Why should one want to use case-folding with XML? XML is case-sensitiv, I think this is nonsense
  93. xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, false);
  94.  
  95. if (!($fp = @fopen($this->file, "r"))) {
  96. die(print("Couldn't open file: $this->file\n"));
  97. }
  98.  
  99. while ($data = fread($fp, 4096)) {
  100. if (!xml_parse($xml_parser, $data, feof($fp))) {
  101. die(sprintf("XML error: %s at line %d\n",
  102. xml_get_current_line_number($xml_parser)));
  103. }
  104. }
  105. }
  106.  
  107. function startElement($parser, $name, $attribs) {
  108. # Adding the additional element to the tree, including attributes
  109. $this->tree[] = $name;
  110.  
  111. $node = new Node($this->tree);
  112. while (list($k, $v) = each($attribs)) {
  113. $node->attributes[$k] = $v;
  114. }
  115. $this->nodes[] = $node;
  116. }
  117.  
  118. function endElement($parser, $name) {
  119. # Adding a new element, describing the end of the tag
  120. # But only, if the Tag has CDATA in it!
  121.  
  122. # Check
  123. if (count($this->nodes) >= 1) {
  124. $prev_node = $this->nodes[count($this->nodes)-1];
  125. if (strlen($prev_node->data) > 0 || $prev_node->name != $name) {
  126. $this->tree[count($this->tree)-1] = "/".$this->tree[count($this->tree)-1];
  127. $this->nodes[] = new Node($this->tree, NULL);
  128. } else {
  129. # Adding a slash to the end of the prev_node
  130. $prev_node->name = $prev_node->name."/"
  131. $this->nodes[count($this->nodes)-1]->name = $this->nodes[count($this->nodes)-1]->name."/"
  132. }
  133. }
  134.  
  135. # Removing the element from the tree
  136. array_pop($this->tree);
  137. }
  138.  
  139. function characterData($parser, $data) {
  140. $data = ltrim($data);
  141. if ($data != "") $this->nodes[count($this->nodes)-1]->add_data($data);
  142. }
  143.  
  144. function process_instruction($parser, $target, $data) {
  145. if (preg_match("/xml:stylesheet/", $target, $match) && preg_match("/type=\"text\/xsl\"/", $data, $match)) {
  146. preg_match("/href=\"(.+)\"/i", $data, $this->PIs);
  147. # print "<b>found xls pi: $PIs[1]</b><br>\n"
  148. }
  149. }
  150.  
  151. function print_nodes() {
  152. # Printing the header
  153. print "<html><head><title>".$this->nodes[0]->name."</title></head>"
  154. print "<body style=\"".$this->format_body."\">\n"
  155.  
  156. # Printing the XML Data
  157. for ($i = 0; $i < count($this->nodes); $i++) {
  158. $node = $this->nodes[$i];
  159.  
  160. # Checking: Empty element
  161. if ($node->name[strlen($node->name)-1] == "/") {
  162. $end_char = "/"
  163. $node->name = substr($node->name, 0, strlen($node->name)-1);
  164. } else {
  165. $end_char = ""
  166. }
  167.  
  168. # Writing whitespaces, but only if it's _no_ closing element that follows
  169. # directly on it's opening element
  170. if (!("/".$this->nodes[$i-1]->name == $node->name)) {
  171. for ($j = 0; $j < $node->level(); $j++) echo $this->format_blanks;
  172. }
  173. echo "<span style=\"".$this->format_bracket."\"><</span><span style=\"".$this->format_element."\">".$node->name."</span>"
  174. if ($node->has_attributes()) {
  175. $keys = array_keys($node->attributes);
  176. for ($j = 0; $j < count($keys); $j++) {
  177. 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);
  178. }
  179. echo " "
  180. }
  181.  
  182. echo "<span style=\"".$this->format_element."\">$end_char</span><span style=\"".$this->format_bracket."\">></span>"
  183.  
  184. if (strlen($node->data) > 0) echo "<span style=\"".$this->format_data."\">".ltrim($node->data)."</span>"
  185. else echo "<br>\n"
  186. }
  187.  
  188. # Printing the footer
  189. print "</body></html>\n"
  190. }
  191. }

Report this snippet  

Comments

RSS Icon Subscribe to comments
Posted By: Abe on March 25, 2008

You forgot to add like 100 ;

Posted By: romver on May 19, 2008

I don`t understant wher umport php file

You need to login to post a comment.