]> git.sesse.net Git - xml-template/blob - xml-template.php
Utilize the undocumented (!!) namespace support.
[xml-template] / xml-template.php
1 <?php
2
3 function XML_Template_process_file($filename, $obj, $clean = 1)
4 {
5         $doc = domxml_open_file($filename);
6         XML_Template_process($doc, $obj, $clean);
7         return $doc;
8 }
9
10 function XML_Template_process($node, $obj, $clean = 1)
11 {
12         if (!is_array($obj)) {                                # overwrite
13                 foreach ($node->child_nodes() as $child) {
14                         $node->remove_child($child);
15                 }
16                 $doc = $node->owner_document();
17                 $node->add_child($doc->create_text_node($obj));
18         # handle overwrite with a DOM object here
19         } else if (is_associative_array($obj)) {              # substitute
20                 foreach ($node->child_nodes() as $child) {
21                         $processed = false;
22
23                         if ($child->node_type() == XML_ELEMENT_NODE) {
24                                 $tag = $child->node_name();
25                                 $attrs = $child->attributes();
26                                 if ($attrs != null) {
27                                         foreach ($child->attributes() as $attr) {
28                                                 if ($attr->namespace_uri() == 'http://template.sesse.net/' && $attr->name() == 'id') {
29                                                         $id = $attr->value();
30                                                         if ($clean) {
31                                                                 $child->remove_attribute($attr->name());
32                                                         }
33                                                 }
34                                         }
35                                 }
36                         
37                                 # check all substitutions to see if we found anything
38                                 # appropriate
39                                 foreach (array_keys($obj) as $key) {
40                                         # FIXME: we would want something like \Q and \E here...
41                                         if (preg_match('/^' . $tag . '\.(.*)$/', $key, $matches) ||
42                                             ($id != null && preg_match('/^#' . $id . '\.(.*)$/', $key, $matches))) {
43                                                 $child->set_attribute($matches[0], $obj[$key]);
44                                         }
45
46                                         if ($processed) {
47                                                 continue;
48                                         }
49                                         if ($key == $tag || ($id != null && $key == ('#'.$id))) {
50                                                 XML_Template_process($child, $obj[$key], $clean);
51                                                 $processed = true;
52                                         }
53                                 }
54                         }
55
56                         if (!$processed) {
57                                 XML_Template_process($child, $obj, $clean);
58                         }
59                 }
60         } else {                                                # repeat
61                 $doc = $node->owner_document();
62                 $frag = $doc->create_element("temporary-fragment");    # ugh
63
64                 foreach ($node->child_nodes() as $child) {
65                         $frag->append_child($child);
66                         $node->remove_child($child);
67                 }
68
69                 foreach ($obj as $instance) {
70                         $newnode = $frag->clone_node(true);
71                         $node->append_child($newnode);
72                         XML_Template_process($newnode, $instance, $clean);
73
74                         # FIXME: clean
75                 }
76
77                 # remove all the <fragment> tags
78
79                 foreach ($node->child_nodes() as $child) {
80                         if ($child->name() != 'temporary-fragment') {
81                                 continue;
82                         }
83                         foreach ($child->child_nodes() as $child2) {
84                                 $node->append_child($child2);
85                         }
86                         $node->remove_child($child);
87                 }       
88
89                 return;
90         }
91
92         # FIXME: clean
93 }
94
95 function is_associative_array($arr)
96 {
97         if (!is_array($arr)) {
98                 return false;
99         }
100         $diff = array_diff(range(0, count($arr) - 1), array_keys($arr));
101         return (count($diff) > 0);
102 }
103 ?>