1 /*******************************************************************************
2 
3         Copyright: Copyright (C) 2008 Kris Bell.  All rights reserved.
4 
5         License:   BSD style: $(LICENSE)
6 
7         version:   Initial release: March 2008      
8 
9         Authors:   Kris
10 
11 *******************************************************************************/
12 
13 module tango.text.xml.DocTester;
14 
15 private import tango.core.Exception;
16 
17 private import tango.text.xml.Document;
18 
19 private import tango.text.convert.Format;
20 
21 private import tango.core.Vararg;
22 
23 /*******************************************************************************
24 
25         Validate a document
26 
27         TODO: add various tests here, or in subclasses, as required
28 
29 *******************************************************************************/
30 
31 protected class DocTester(T)
32 {
33         private alias Document!(T) Doc;         /// the typed document
34         private alias Doc.Node     Node;        /// generic document node
35 
36         /***********************************************************************
37         
38                 Generate a text representation of the document tree
39 
40         ***********************************************************************/
41         
42         final void validate (Doc doc)
43         {     
44                 validate (doc.elements);  
45         }
46         
47         /***********************************************************************
48         
49                 Generate a representation of the given node-subtree 
50 
51         ***********************************************************************/
52         
53         final void validate (Node node)
54         {
55                 switch (node.id)
56                        {
57                        case XmlNodeType.Document:
58                             foreach (n; node.children)
59                                      validate (n);
60                             break;
61         
62                        case XmlNodeType.Element:
63                             element (node);
64 
65                             foreach (n; node.attributes)
66                                      attribute (n);
67 
68                             foreach (n; node.children)
69                                      validate (n);
70                             break;
71         
72                        case XmlNodeType.Attribute:
73                             attribute (node);
74                             break;
75         
76                        case XmlNodeType.Data:
77                             data (node);
78                             break;
79         
80                        case XmlNodeType.Comment:
81                             comment (node);
82                             break;
83         
84                        case XmlNodeType.PI:
85                             pi (node);
86                             break;
87                 
88                        case XmlNodeType.CData:
89                             cdata (node);
90                             break;
91                 
92                        case XmlNodeType.Doctype:
93                             doctype (node);
94                             break;
95                        }
96         }
97 
98         /***********************************************************************
99         
100                 validate an element
101 
102         ***********************************************************************/
103         
104         void element (Node node)
105         {
106                 uniqueAttrNames (node);
107         }
108 
109         /***********************************************************************
110         
111                 validate an attribute
112 
113         ***********************************************************************/
114         
115         void attribute (Node node)
116         {
117         }
118 
119         /***********************************************************************
120         
121                 validate a data node
122 
123         ***********************************************************************/
124         
125         void data (Node node)
126         {
127         }
128 
129         /***********************************************************************
130         
131                 validate a comment node
132 
133         ***********************************************************************/
134         
135         void comment (Node node)
136         {
137         }
138 
139         /***********************************************************************
140         
141                 validate a pi node
142 
143         ***********************************************************************/
144         
145         void pi (Node node)
146         {
147         }
148 
149         /***********************************************************************
150         
151                 validate a cdata node
152 
153         ***********************************************************************/
154         
155         void cdata (Node node)
156         {
157         }
158 
159         /***********************************************************************
160         
161                 validate a doctype node
162 
163         ***********************************************************************/
164         
165         void doctype (Node node)
166         {
167         }
168 
169         /***********************************************************************
170         
171                 Ensure attribute names are unique within the element 
172 
173         ***********************************************************************/
174         
175         static void uniqueAttrNames (Node node)
176         {
177                 T[128]  name1 = void,
178                         name2 = void;
179 
180                 // non-optimal, but is it critical?
181                 foreach (attr; node.attributes)
182                         {
183                         auto name = attr.name (name1);
184                         auto next = attr.nextSibling;
185                         while (next !is null)
186                               {
187                               if (name == next.name(name2))
188                                   error ("duplicate attribute name '{}' for element '{}'", 
189                                           name, node.name(name2));
190                               next = attr.nextSibling;
191                               }
192                         }
193         }
194 
195         /***********************************************************************
196         
197                 halt validation
198 
199         ***********************************************************************/
200         
201         static void error (const(char)[] format, ...)
202         {
203                 throw new TextException (Format.convert(_arguments, _argptr, format).idup);
204         }
205 }
206 
207 
208 
209 
210 /*******************************************************************************
211 
212 *******************************************************************************/
213 
214 debug (DocTester)
215 {
216         void main()
217         {
218                 auto v = new DocTester!(char);
219         }
220 }