123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
|
/*******************************************************************************
Copyright: Copyright (C) 2008 Kris Bell. All rights reserved.
License: BSD style: $(LICENSE)
version: Initial release: March 2008
Authors: Kris
*******************************************************************************/
module tango.text.xml.DocTester;
private import tango.core.Exception;
private import tango.text.xml.Document;
private import tango.text.convert.Format;
private import tango.core.Vararg;
/*******************************************************************************
Validate a document
TODO: add various tests here, or in subclasses, as required
*******************************************************************************/
protected class DocTester(T)
{
private alias Document!(T) Doc; /// the typed document
private alias Doc.Node Node; /// generic document node
/***********************************************************************
Generate a text representation of the document tree
***********************************************************************/
final void validate (Doc doc)
{
validate (doc.elements);
}
/***********************************************************************
Generate a representation of the given node-subtree
***********************************************************************/
final void validate (Node node)
{
switch (node.id)
{
case XmlNodeType.Document:
foreach (n; node.children)
validate (n);
break;
case XmlNodeType.Element:
element (node);
foreach (n; node.attributes)
attribute (n);
foreach (n; node.children)
validate (n);
break;
case XmlNodeType.Attribute:
attribute (node);
break;
case XmlNodeType.Data:
data (node);
break;
case XmlNodeType.Comment:
comment (node);
break;
case XmlNodeType.PI:
pi (node);
break;
case XmlNodeType.CData:
cdata (node);
break;
case XmlNodeType.Doctype:
doctype (node);
break;
}
}
/***********************************************************************
validate an element
***********************************************************************/
void element (Node node)
{
uniqueAttrNames (node);
}
/***********************************************************************
validate an attribute
***********************************************************************/
void attribute (Node node)
{
}
/***********************************************************************
validate a data node
***********************************************************************/
void data (Node node)
{
}
/***********************************************************************
validate a comment node
***********************************************************************/
void comment (Node node)
{
}
/***********************************************************************
validate a pi node
***********************************************************************/
void pi (Node node)
{
}
/***********************************************************************
validate a cdata node
***********************************************************************/
void cdata (Node node)
{
}
/***********************************************************************
validate a doctype node
***********************************************************************/
void doctype (Node node)
{
}
/***********************************************************************
Ensure attribute names are unique within the element
***********************************************************************/
static void uniqueAttrNames (Node node)
{
T[128] name1 = void,
name2 = void;
// non-optimal, but is it critical?
foreach (attr; node.attributes)
{
auto name = attr.name (name1);
auto next = attr.nextSibling;
while (next !is null)
{
if (name == next.name(name2))
error ("duplicate attribute name '{}' for element '{}'",
name, node.name(name2));
next = attr.nextSibling;
}
}
}
/***********************************************************************
halt validation
***********************************************************************/
static void error (const(char)[] format, ...)
{
throw new TextException (Format.convert(_arguments, _argptr, format).idup);
}
}
/*******************************************************************************
*******************************************************************************/
debug (DocTester)
{
void main()
{
auto v = new DocTester!(char);
}
}
|