1 <?php
2 3 4 5 6
7 class XML extends Object {
8 protected $parser;
9 protected $context, $attributeStore;
10 protected $parsed;
11 protected $collatedText;
12
13
14 function tidyXHTML($content) {
15 $cleanFile = TEMP_FOLDER . "/cleaner.tmp";
16 $fh = fopen($cleanFile,"wb");
17 fwrite($fh, $content);
18 fclose($fh);
19
20 if(file_exists($cleanFile)) {
21 $result = `tidy -asxhtml $cleanFile`;
22 unlink($cleanFile);
23 return $result;
24 }
25 }
26
27 function parse($content, $recursive = false) {
28 $this->parser = xml_parser_create('UTF-8');
29
30
31 $content = ereg_replace('encoding="[^"]+"','encoding="utf-8"', $content);
32
33 xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, false);
34
35 xml_set_object($this->parser, $this);
36 xml_set_element_handler($this->parser, "tag_open", "tag_close");
37 xml_set_character_data_handler($this->parser, "cdata");
38
39 $this->parsed = null;
40 $this->context = array();
41 $this->attributeStore = array();
42
43 xml_parse($this->parser, $content);
44
45
46 if(xml_get_error_code($this->parser) == 32 && !$recursive) {
47 $content = ereg_replace('encoding="[^"]+"','encoding="utf-8"', $content);
48 return $this->parse($content, true);
49 }
50
51 if($err = xml_get_error_code($this->parser)) {
52 user_error("XML parser broke with error $err:" . xml_error_string($err), E_USER_ERROR);
53 }
54
55 return $this->parsed;
56 }
57
58 function inContext() {
59 $items = func_get_args();
60 $i=0;
61 foreach($items as $item) {
62 while($i < sizeof($this->context)) {
63 if($this->context[$i] == $item) break;
64 $i++;
65 }
66 if($this->context[$i] != $item) return false;
67 }
68 return true;
69 }
70
71 function stackActionFor($tag) {
72 for($i=sizeof($this->contextStack)-1;$i>=0;$i--) {
73 if($this->context[$i]['tag'] == $tag) return $this->contextStack[$i]['action'];
74 }
75 }
76
77 function tag_open($parser, $tag, $attributes) {
78
79 $tag = ereg_replace('[^:]+:','',$tag);
80 if($attributes) foreach($attributes as $k => $v) $newAttributes[ereg_replace('[^:]+:','',$k)] = $v;
81 $attributes = isset($newAttributes) ? $newAttributes : $attributes;
82
83
84 if(isset($attributes['class'])) {
85 $this->context[] = "$tag.{$attributes['class']}";
86 } else {
87 $this->context[] = $tag;
88 }
89 $this->attributeStore[] = $attributes;
90
91 $this->collatedText = "";
92
93 $tagProcessorFunc = "process_$tag";
94 if($this->hasMethod($tagProcessorFunc)) {
95 $this->$tagProcessorFunc($attributes);
96 }elseif($this->hasMethod($tagProcessorFunc = "process_tag")){
97 $this->$tagProcessorFunc($tag, $attributes);
98 }
99
100
101 if($attributes) foreach($attributes as $k => $v) {
102 $attProcessorFunc = "processatt_$k";
103 if($this->hasMethod($attProcessorFunc)) {
104 $this->$attProcessorFunc($tag, $attributes);
105 }
106 }
107 }
108
109 function tag_close($parser, $tag) {
110 $tag = ereg_replace('[^:]+:','',$tag);
111
112 array_pop($this->context);
113 $attributes = array_pop($this->attributeStore);
114
115 if(method_exists($this, $funcName = "process_{$tag}_end")) {
116 $this->$funcName($this->collatedText, $attributes);
117 }elseif(method_exists($this,$funcName = "process_tag_end")){
118
119 $this->$funcName($tag,$this->collatedText, $attributes);
120 }
121
122 $this->collatedText = "";
123 }
124
125 function cdata($parser, $cdata) {
126 $this->collatedText .= $cdata;
127 }
128 }
[Raise a SilverStripe Framework issue/bug](https://github.com/silverstripe/silverstripe-framework/issues/new)
- [Raise a SilverStripe CMS issue/bug](https://github.com/silverstripe/silverstripe-cms/issues/new)
- Please use the
Silverstripe Forums to ask development related questions.
-