Andrew's Web Libraries (AWL)
Loading...
Searching...
No Matches
XMLDocument.php
1<?php
13require_once("XMLElement.php");
14
21
29 private $namespaces;
30
35 private $prefixes;
36
41 private $root;
42
48 public $next_prefix;
49
55 function __construct( $namespaces = null ) {
56 $this->namespaces = array();
57 $this->prefixes = array();
58 if ( $namespaces != null ) {
59 foreach( $namespaces AS $ns => $prefix ) {
60 $this->namespaces[$ns] = $prefix;
61 $this->prefixes[$prefix] = $prefix;
62 }
63 }
64 $this->next_prefix = 0;
65 }
66
73 function AddNamespace( $namespace, $prefix = null ) {
74 if ( !isset($this->namespaces[$namespace]) ) {
75 if ( isset($prefix) && ($prefix == "" || isset($this->prefixes[$prefix])) ) $prefix = null;
76 if ( $prefix == null ) {
77 // Try and build a prefix based on the first alphabetic character of the last element of the namespace
78 if ( preg_match('/^(.*):([^:]+)$/', $namespace, $matches) ) {
79 $alpha = preg_replace( '/[^a-z]/i', '', $matches[2] );
80 $prefix = strtoupper(substr($alpha,0,1));
81 }
82 else {
83 $prefix = 'X';
84 }
85 $i = "";
86 if ( isset($this->prefixes[$prefix]) ) {
87 for ( $i=1; $i<10 && isset($this->prefixes["$prefix$i"]); $i++ ) {
88 }
89 }
90 if ( isset($this->prefixes["$prefix$i"]) ) {
91 dbg_error_log("ERROR", "Cannot find a free prefix for this namespace");
92 exit;
93 }
94 $prefix = "$prefix$i";
95 dbg_error_log("XMLDocument", "auto-assigning prefix of '%s' for ns of '%s'", $prefix, $namespace );
96 }
97 else if ( $prefix == "" || isset($this->prefixes[$prefix]) ) {
98 dbg_error_log("ERROR", "Cannot assign the same prefix to two different namespaces");
99 exit;
100 }
101
102 $this->prefixes[$prefix] = $prefix;
103 $this->namespaces[$namespace] = $prefix;
104 }
105 else {
106 if ( isset($this->namespaces[$namespace]) && $this->namespaces[$namespace] != $prefix ) {
107 dbg_error_log("ERROR", "Cannot use the same namespace with two different prefixes");
108 exit;
109 }
110 $this->prefixes[$prefix] = $prefix;
111 $this->namespaces[$namespace] = $prefix;
112 }
113 }
114
118 function DefaultNamespace() {
119 foreach( $this->namespaces AS $k => $v ) {
120 if ( $v == '' ) {
121 return $k;
122 }
123 }
124 return '';
125 }
126
131 function GetXmlNsArray() {
132
133 $ns = array();
134 foreach( $this->namespaces AS $n => $p ) {
135 if ( $p == "" ) $ns["xmlns"] = $n; else $ns["xmlns:$p"] = $n;
136 }
137
138 return $ns;
139 }
140
141
151 function Tag( $in_tag, $namespace=null, $prefix=null ) {
152
153 if ( $namespace == null ) {
154 // Attempt to split out from namespace:tag
155 if ( preg_match('/^(.*):([^:]+)$/', $in_tag, $matches) ) {
156 $namespace = $matches[1];
157 $tag = $matches[2];
158 }
159 else {
160 // There is nothing we can do here
161 return $in_tag;
162 }
163 }
164 else {
165 $tag = $in_tag;
166 }
167
168 if ( !isset($this->namespaces[$namespace]) ) {
169 $this->AddNamespace( $namespace, $prefix );
170 }
171 $prefix = $this->namespaces[$namespace];
172
173 return $prefix . ($prefix == "" ? "" : ":") . $tag;
174 }
175
176 static public $ns_dav = 'DAV:';
177 static public $ns_caldav = 'urn:ietf:params:xml:ns:caldav';
178 static public $ns_carddav = 'urn:ietf:params:xml:ns:carddav';
179 static public $ns_calendarserver = 'http://calendarserver.org/ns/';
180
191 function NSElement( &$element, $in_tag, $content=false, $attributes=false, $namespace=null ) {
192 if ( $namespace == null && preg_match('/^(.*):([^:]+)$/', $in_tag, $matches) ) {
193 $namespace = $matches[1];
194 if ( preg_match('{^[A-Z][A-Z0-9]*$}', $namespace ) ) {
195 throw new Exception("Dodgy looking namespace from '".$in_tag."'!");
196 }
197 $tag = $matches[2];
198 }
199 else {
200 $tag = $in_tag;
201 if ( isset($namespace) ) {
202 $tag = str_replace($namespace.':', '', $tag);
203 }
204 }
205
206 if ( isset($namespace) && !isset($this->namespaces[$namespace]) ) $this->AddNamespace( $namespace );
207 return $element->NewElement( $tag, $content, $attributes, $namespace );
208 }
209
210
219 function DAVElement( &$element, $tag, $content=false, $attributes=false ) {
220 if ( !isset($this->namespaces[self::$ns_dav]) ) $this->AddNamespace( self::$ns_dav, '' );
221 return $this->NSElement( $element, $tag, $content, $attributes, self::$ns_dav );
222 }
223
232 function CalDAVElement( &$element, $tag, $content=false, $attributes=false ) {
233 if ( !isset($this->namespaces[self::$ns_caldav]) ) $this->AddNamespace( self::$ns_caldav, 'C' );
234 return $this->NSElement( $element, $tag, $content, $attributes, self::$ns_caldav );
235 }
236
237
246 function CardDAVElement( &$element, $tag, $content=false, $attributes=false ) {
247 if ( !isset($this->namespaces[self::$ns_carddav]) ) $this->AddNamespace( self::$ns_carddav, 'VC' );
248 return $this->NSElement( $element, $tag, $content, $attributes, self::$ns_carddav );
249 }
250
251
260 function CalendarserverElement( &$element, $tag, $content=false, $attributes=false ) {
261 if ( !isset($this->namespaces[self::$ns_calendarserver]) ) $this->AddNamespace( self::$ns_calendarserver, 'A' );
262 return $this->NSElement( $element, $tag, $content, $attributes, self::$ns_calendarserver );
263 }
264
265
272 function NewXMLElement( $in_tag, $content=false, $attributes=false, $xmlns=null ) {
273 if ( $xmlns == null && preg_match('/^(.*):([^:]+)$/', $in_tag, $matches) ) {
274 $xmlns = $matches[1];
275 $tagname = $matches[2];
276 }
277 else {
278 $tagname = $in_tag;
279 }
280
281 if ( isset($xmlns) && !isset($this->namespaces[$xmlns]) ) $this->AddNamespace( $xmlns );
282 return new XMLElement($tagname, $content, $attributes, $xmlns );
283 }
284
295 function Render( $root, $content=false, $attributes=false, $xmlns=null ) {
296 if ( is_object($root) ) {
298 $this->root = $root;
299 }
300 else {
302 $this->root = $this->NewXMLElement( $root, $content, $attributes, $xmlns );
303 }
304
308 foreach( $this->namespaces AS $n => $p ) {
309 $this->root->SetAttribute( 'xmlns'.($p == '' ? '' : ':') . $p, $n);
310 }
311
313 return $this->root->Render(0,'<?xml version="1.0" encoding="utf-8" ?>');
314 }
315
322 function href($url) {
323 if ( is_array($url) ) {
324 $set = array();
325 foreach( $url AS $href ) {
326 $set[] = $this->href( $href );
327 }
328 return $set;
329 }
330 if ( preg_match('[@+ ]',$url) ) {
331 trace_bug('URL "%s" was not encoded before call to XMLDocument::href()', $url );
332 $url = str_replace( '%2F', '/', rawurlencode($url));
333 }
334 return $this->NewXMLElement('href', $url, false, 'DAV:');
335 }
336
337}
338
339
NewXMLElement( $in_tag, $content=false, $attributes=false, $xmlns=null)
Render( $root, $content=false, $attributes=false, $xmlns=null)
CalendarserverElement(&$element, $tag, $content=false, $attributes=false)
__construct( $namespaces=null)
DAVElement(&$element, $tag, $content=false, $attributes=false)
Tag( $in_tag, $namespace=null, $prefix=null)
NSElement(&$element, $in_tag, $content=false, $attributes=false, $namespace=null)
CardDAVElement(&$element, $tag, $content=false, $attributes=false)
CalDAVElement(&$element, $tag, $content=false, $attributes=false)
AddNamespace( $namespace, $prefix=null)