]> git.sesse.net Git - xml-template/blob - xml-template.php
eb41c10c3d69e82cdc2a6a4106989f3511a2c4e4
[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, $nsup = array())
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                                                 # FIXME: xmlns, nsuri?
29                                                 if ($attr->name() == 'id') {
30                                                         $id = $attr->value();
31                                                         if ($clean) {
32                                                                 $child->remove_attribute($attr->name());
33                                                         }
34                                                 }
35                                         }
36                                 }
37                         
38                                 # check all substitutions to see if we found anything
39                                 # appropriate
40                                 foreach (array_keys($obj) as $key) {
41                                         # FIXME: we would want something like \Q and \E here...
42                                         if (preg_match('/^' . $tag . '\.(.*)$/', $key, $matches) ||
43                                             ($id != null && preg_match('/^#' . $id . '\.(.*)$/', $key, $matches))) {
44                                                 $child->set_attribute($matches[0], $obj[$key]);
45                                         }
46
47                                         if ($processed) {
48                                                 continue;
49                                         }
50                                         if ($key == $tag || ($id != null && $key == ('#'.$id))) {
51                                                 XML_Template_process($child, $obj[$key], $clean, $nsup);
52                                                 $processed = true;
53                                         }
54                                 }
55                         }
56
57                         if (!$processed) {
58                                 XML_Template_process($child, $obj, $clean, $nsup);
59                         }
60                 }
61         } else {                                                # repeat
62                 $doc = $node->owner_document();
63                 $frag = $doc->create_element("temporary-fragment");    # ugh
64
65                 foreach ($node->child_nodes() as $child) {
66                         $frag->append_child($child);
67                         $node->remove_child($child);
68                 }
69
70                 foreach ($obj as $instance) {
71                         $newnode = $frag->clone_node(true);
72                         $node->append_child($newnode);
73                         XML_Template_process($newnode, $instance, $clean, $nsup);
74
75                         # FIXME: clean
76                 }
77
78                 # remove all the <fragment> tags
79
80                 foreach ($node->child_nodes() as $child) {
81                         if ($child->name() != 'temporary-fragment') {
82                                 continue;
83                         }
84                         foreach ($child->child_nodes() as $child2) {
85                                 $node->append_child($child2);
86                         }
87                         $node->remove_child($child);
88                 }       
89
90                 return;
91         }
92
93         # FIXME: clean
94 }
95
96 function is_associative_array($arr)
97 {
98         if (!is_array($arr)) {
99                 return false;
100         }
101         $diff = array_diff(range(0, count($arr) - 1), array_keys($arr));
102         return (count($diff) > 0);
103 }
104 ?>