1 <?php rcs_id('$Id: XmlElement.php,v 1.3 2002-01-21 16:59:01 dairiki Exp $');
3 * Code for writing XML.
11 function XmlElement ($tagname /* , $attr_or_content , ...*/) {
12 $this->_tag = $tagname;
13 $this->_content = array();
15 if (func_num_args() > 1)
16 $this->_init(array_slice(func_get_args(), 1));
18 $this->_attr = array();
21 function _init ($args) {
22 assert(is_array($args));
26 if (is_array($args[0]))
27 $this->_attr = array_shift($args);
29 $this->_attr = array();
30 if (count($args) > 1 && ! $args[0])
34 if (count($args) == 1 && is_array($args[0]))
35 $this->_content = $args[0];
37 $this->_content = $args;
44 function setAttr ($attr, $value = false) {
45 if (is_array($attr)) {
46 assert($value === false);
47 foreach ($attr as $a => $v)
52 assert(is_string($attr));
53 if ($value === false) {
54 unset($this->_attr[$attr]);
58 $this->_attr[$attr] = (string) $value;
61 function getAttr ($attr) {
62 if (isset($this->_attr[$attr]))
63 return $this->_attr[$attr];
68 function pushContent ($args /*, ...*/) {
69 $c = &$this->_content;
70 if (func_num_args() != 1 || ! is_array($args))
71 $args = func_get_args();
72 array_splice($c, count($c), 0, $args);
75 function unshiftContent ($args /*, ...*/) {
76 $c = &$this->_content;
77 if (func_num_args() != 1 || ! is_array($args))
78 $args = func_get_args();
79 array_splice($c, 0, 0, $args);
82 function getContent () {
83 return $this->_content;
86 function _startTag() {
87 $start = "<" . $this->_tag;
88 foreach ($this->_attr as $attr => $val)
89 $start .= " $attr=\"" . $this->_quoteAttr($val) . '"';
94 function _emptyTag() {
95 return substr($this->_startTag(), 0, -1) . "/>";
99 function printXML () {
101 if ($this->isEmpty()) {
102 echo $this->_emptyTag();
105 $sep = $this->hasInlineContent() ? "" : "\n";
106 echo $this->_startTag() . $sep;
107 foreach ($this->_content as $c) {
111 echo "</$this->_tag>";
116 if ($this->isEmpty())
117 return $this->_emptyTag();
119 $sep = $this->hasInlineContent() ? "" : "\n";
120 $xml = $this->_startTag() . $sep;
121 foreach ($this->_content as $c)
122 $xml .= AsXML($c) . $sep;
123 return $xml . "</$this->_tag>";
126 function asString () {
128 foreach ($this->_content as $c)
129 $val .= AsString($c);
133 function isEmpty () {
134 return empty($this->_content);
137 function hasInlineContent () {
138 // FIXME: This is a hack.
139 if (empty($this->_content))
141 if (is_object($this->_content[0]))
146 function _quote ($string) {
147 return str_replace('<', '<',
148 str_replace('>', '>',
149 str_replace('&', '&', $string)));
152 function _quoteAttr ($value) {
153 return str_replace('"', '"', XmlElement::_quote($value));
158 function RawXml ($xml_text) {
159 $this->_xml = $xml_text;
162 function printXML () {
171 class FormattedText {
172 function FormattedText ($fs /* , ... */) {
174 $this->_init(func_get_args());
178 function _init ($args) {
179 $this->_fs = array_shift($args);
181 // PHP's sprintf doesn't support variable width specifiers,
182 // like sprintf("%*s", 10, "x"); --- so we won't either.
184 if (! preg_match_all('/(?<!%)%(\d+)\$/x', $this->_fs, $m)) {
185 $this->_args = $args;
188 // Format string has '%2$s' style argument reordering.
189 // PHP doesn't support this.
190 if (preg_match('/(?<!%)%[- ]?\d*[^- \d$]/x', $fmt))
191 // literal variable name substitution only to keep locale
192 // strings uncluttered
193 trigger_error(sprintf(_("Can't mix '%s' with '%s' type format strings"),
194 '%1\$s','%s'), E_USER_WARNING);
196 $this->_fs = preg_replace('/(?<!%)%\d+\$/x', '%', $this->_fs);
198 $this->_args = array();
199 foreach($m[1] as $argnum) {
200 if ($argnum < 1 || $argnum > count($args))
201 trigger_error(sprintf(_("%s: argument index out of range"),
202 $argnum), E_USER_WARNING);
203 $this->_args[] = $args[$argnum - 1];
209 // Not all PHP's have vsprintf, so...
210 $args[] = XmlElement::_quote($this->_fs);
211 foreach ($this->_args as $arg)
212 $args[] = AsXML($arg);
213 return call_user_func_array('sprintf', $args);
216 function printXML () {
217 // Not all PHP's have vsprintf, so...
218 $args[] = XmlElement::_quote($this->_fs);
219 foreach ($this->_args as $arg)
220 $args[] = AsXML($arg);
221 call_user_func_array('printf', $args);
224 function asString() {
225 $args = $this->_args;
226 array_unshift($args, $this->_fs);
227 return call_user_func_array('sprintf', $args);
231 function PrintXML ($val) {
232 if (is_object($val)) {
233 if (method_exists($val, 'printxml'))
234 return $val->printXML();
235 elseif (method_exists($val, 'asxml')) {
239 elseif (method_exists($val, 'asstring'))
240 $val = $val->asString();
242 elseif (is_array($val)) {
247 echo (string)XmlElement::_quote($val);
250 function AsXML ($val) {
251 if (is_object($val)) {
252 if (method_exists($val, 'asxml'))
253 return $val->asXML();
254 elseif (method_exists($val, 'asstring'))
255 $val = $val->asString();
257 elseif (is_array($val)) {
264 return XmlElement::_quote((string)$val);
267 function AsString ($val) {
268 if (can($val, 'asString'))
269 return $val->asString();
270 elseif (is_array($val)) {
273 $str .= AsString($x);
276 return (string) $val;
280 function fmt ($fs /* , ... */) {
281 $s = new FormattedText(false);
283 $args = func_get_args();
284 $args[0] = gettext($args[0]);
289 // (c-file-style: "gnu")
294 // c-hanging-comment-ender-p: nil
295 // indent-tabs-mode: nil