using System.Text;
using System.Xml.Schema;
using Mono.Xml;
+using Mono.Xml.Schema;
namespace System.Xml {
public class XmlValidatingReader : XmlReader, IXmlLineInfo {
EntityHandling entityHandling;
XmlReader sourceReader;
+ XmlTextReader xmlTextReader;
XmlReader validatingReader;
XmlResolver resolver;
+ bool specifiedResolver;
ValidationType validationType;
XmlSchemaCollection schemas;
DTDValidatingReader dtdReader;
+ IHasXmlSchemaInfo schemaInfo;
+ StringBuilder storedCharacters;
#endregion // Fields
#region Constructors
- [MonoTODO]
public XmlValidatingReader (XmlReader reader)
- : base ()
{
this.sourceReader = reader;
+ this.xmlTextReader = reader as XmlTextReader;
entityHandling = EntityHandling.ExpandEntities;
validationType = ValidationType.Auto;
schemas = new XmlSchemaCollection ();
+ storedCharacters = new StringBuilder ();
}
public XmlValidatingReader (Stream xmlFragment, XmlNodeType fragType, XmlParserContext context)
#region Properties
public override int AttributeCount {
- [MonoTODO]
get { return validatingReader == null ? 0 : validatingReader.AttributeCount; }
}
public override string BaseURI {
- [MonoTODO]
get { return validatingReader == null ? sourceReader.BaseURI : validatingReader.BaseURI; }
}
+ // This property for this class always return true.
public override bool CanResolveEntity {
- get { return validatingReader == null ? false : validatingReader.CanResolveEntity; }
+ get { return true; }
}
public override int Depth {
- [MonoTODO]
get { return validatingReader == null ? 0 : validatingReader.Depth; }
}
public Encoding Encoding {
- [MonoTODO]
- get { throw new NotImplementedException (); }
+ get {
+ if (xmlTextReader != null)
+ return xmlTextReader.Encoding;
+ else
+ throw new NotSupportedException ("Encoding is supported only for XmlTextReader.");
+ }
}
public EntityHandling EntityHandling {
}
public override bool EOF {
- [MonoTODO]
get { return validatingReader == null ? false : validatingReader.EOF; }
}
public override bool HasValue {
- [MonoTODO]
get { return validatingReader == null ? false : validatingReader.HasValue; }
}
public override bool IsDefault {
- [MonoTODO]
get { return validatingReader == null ? false : validatingReader.IsDefault; }
}
public override bool IsEmptyElement {
- [MonoTODO]
get { return validatingReader == null ? false : validatingReader.IsEmptyElement; }
}
public override string this [int i] {
- [MonoTODO]
- get { return validatingReader [i]; }
+ get {
+ if (validatingReader == null)
+ throw new IndexOutOfRangeException ("Reader is not started.");
+ return validatingReader [i];
+ }
}
public override string this [string name] {
- [MonoTODO]
- get { return validatingReader == null ? String.Empty : validatingReader [name]; }
+ get { return validatingReader == null ? null : validatingReader [name]; }
}
public override string this [string localName, string namespaceName] {
- [MonoTODO]
- get { return validatingReader == null ? String.Empty : validatingReader [localName, namespaceName]; }
+ get { return validatingReader == null ? null : validatingReader [localName, namespaceName]; }
}
int IXmlLineInfo.LineNumber {
get {
+ if (IsDefault)
+ return 0;
IXmlLineInfo info = validatingReader as IXmlLineInfo;
return info != null ? info.LineNumber : 0;
}
int IXmlLineInfo.LinePosition {
get {
+ if (IsDefault)
+ return 0;
IXmlLineInfo info = validatingReader as IXmlLineInfo;
return info != null ? info.LinePosition : 0;
}
}
public override string LocalName {
- [MonoTODO]
- get { return validatingReader == null ? String.Empty : validatingReader.LocalName; }
+ get {
+ if (validatingReader == null)
+ return String.Empty;
+ else if (Namespaces)
+ return validatingReader.LocalName;
+ else
+ return validatingReader.Name;
+ }
}
public override string Name {
- [MonoTODO]
get { return validatingReader == null ? String.Empty : validatingReader.Name; }
}
- [MonoTODO]
public bool Namespaces {
get {
- XmlTextReader xtr = sourceReader as XmlTextReader;
- if (xtr != null)
- return xtr.Namespaces;
+ if (xmlTextReader != null)
+ return xmlTextReader.Namespaces;
else
- throw new NotImplementedException ();
+ return true;
}
set {
- XmlTextReader xtr = sourceReader as XmlTextReader;
- if (xtr != null)
- xtr.Namespaces = value;
+ if (ReadState != ReadState.Initial)
+ throw new InvalidOperationException ("Namespaces have to be set before reading.");
+
+ if (xmlTextReader != null)
+ xmlTextReader.Namespaces = value;
else
- throw new NotImplementedException ();
+ throw new NotSupportedException ("Property 'Namespaces' is supported only for XmlTextReader.");
}
}
public override string NamespaceURI {
- [MonoTODO]
- get { return validatingReader == null ? String.Empty : validatingReader.NamespaceURI; }
+ get {
+ if (validatingReader == null)
+ return String.Empty;
+ else if (Namespaces)
+ return validatingReader.NamespaceURI;
+ else
+ return String.Empty;
+ }
}
public override XmlNameTable NameTable {
- [MonoTODO]
- get { return validatingReader == null ? null : validatingReader.NameTable; }
+ get { return validatingReader == null ? sourceReader.NameTable : validatingReader.NameTable; }
}
public override XmlNodeType NodeType {
- [MonoTODO]
get { return validatingReader == null ? XmlNodeType.None : validatingReader.NodeType; }
}
- public override string Prefix {
- [MonoTODO]
+ public override string Prefix {
get { return validatingReader == null ? String.Empty : validatingReader.Prefix; }
}
public override char QuoteChar {
- [MonoTODO]
- get { return validatingReader == null ? '"' : validatingReader.QuoteChar; }
+ get { return validatingReader == null ? sourceReader.QuoteChar : validatingReader.QuoteChar; }
}
- [MonoTODO ("confirm which reader should be returned.")]
public XmlReader Reader {
get { return sourceReader; }
}
public override ReadState ReadState {
- [MonoTODO]
- get {
+ get {
if (validatingReader == null)
return ReadState.Initial;
return validatingReader.ReadState;
}
public object SchemaType {
- [MonoTODO]
- get { throw new NotImplementedException (); }
+ get { return schemaInfo.SchemaType; }
}
- [MonoTODO]
+// [MonoTODO] We decided not to support XDR schema. It is obsolete.
public ValidationType ValidationType {
get { return validationType; }
set {
case ValidationType.Auto:
case ValidationType.DTD:
case ValidationType.None:
+ case ValidationType.Schema:
validationType = value;
break;
- case ValidationType.Schema:
case ValidationType.XDR:
- throw new NotImplementedException ();
+ throw new NotSupportedException ();
}
}
}
public override string Value {
- [MonoTODO]
get { return validatingReader == null ? String.Empty : validatingReader.Value; }
}
public override string XmlLang {
- [MonoTODO]
get { return validatingReader == null ? String.Empty : validatingReader.XmlLang; }
}
public XmlResolver XmlResolver {
- [MonoTODO]
set {
+ specifiedResolver = true;
resolver = value;
+ /*
+ XsdValidatingReader xsvr = validatingReader as XsdValidatingReader;
+ if (xsvr != null)
+ xsvr.XmlResolver = value;
+ */
DTDValidatingReader dvr = validatingReader as DTDValidatingReader;
if (dvr != null)
dvr.XmlResolver = value;
-// XmlSchemaValidatingReader xsvr = validatingReader as XmlSchemaValidatingReader;
-// if (xsvr != null)
-// xsvr.XmlResolver = value;
}
}
public override XmlSpace XmlSpace {
- [MonoTODO]
get { return validatingReader == null ? XmlSpace.None : validatingReader.XmlSpace; }
}
#region Methods
- [MonoTODO]
public override void Close ()
{
- validatingReader.Close ();
+ if (validatingReader == null)
+ sourceReader.Close ();
+ else
+ validatingReader.Close ();
}
- [MonoTODO]
public override string GetAttribute (int i)
{
- return validatingReader.GetAttribute (i);
+ return this [i];
}
- [MonoTODO]
public override string GetAttribute (string name)
{
- return validatingReader.GetAttribute (name);
+ return this [name];
}
- [MonoTODO]
public override string GetAttribute (string localName, string namespaceName)
{
- return validatingReader.GetAttribute (localName, namespaceName);
+ return this [localName, namespaceName];
}
internal XmlParserContext GetInternalParserContext ()
return info != null ? info.HasLineInfo () : false;
}
- [MonoTODO]
public override string LookupNamespace (string prefix)
{
- return validatingReader.LookupNamespace (prefix);
+ if (validatingReader != null)
+ return sourceReader.LookupNamespace (prefix);
+ else
+ return validatingReader.LookupNamespace (prefix);
}
- [MonoTODO]
public override void MoveToAttribute (int i)
{
- validatingReader.MoveToAttribute (i);
+ if (validatingReader == null)
+ throw new IndexOutOfRangeException ("Reader is not started.");
+ else
+ validatingReader.MoveToAttribute (i);
}
- [MonoTODO]
public override bool MoveToAttribute (string name)
{
+ if (validatingReader == null)
+ return false;
return validatingReader.MoveToAttribute (name);
}
- [MonoTODO]
public override bool MoveToAttribute (string localName, string namespaceName)
{
+ if (validatingReader == null)
+ return false;
return validatingReader.MoveToAttribute (localName, namespaceName);
}
- [MonoTODO]
public override bool MoveToElement ()
{
+ if (validatingReader == null)
+ return false;
return validatingReader.MoveToElement ();
}
- [MonoTODO]
public override bool MoveToFirstAttribute ()
{
+ if (validatingReader == null)
+ return false;
return validatingReader.MoveToFirstAttribute ();
}
- [MonoTODO]
public override bool MoveToNextAttribute ()
{
+ if (validatingReader == null)
+ return false;
return validatingReader.MoveToNextAttribute ();
}
- [MonoTODO]
+// [MonoTODO] We decided not to support XDR schema. It is obsolete.
public override bool Read ()
{
if (ReadState == ReadState.Initial) {
switch (ValidationType) {
case ValidationType.Auto:
case ValidationType.None:
- if (schemas.Count > 0)
- goto case ValidationType.Schema;
- else
- goto case ValidationType.DTD;
+ goto case ValidationType.Schema; // might be specified by xsi:schemaLocation.
case ValidationType.DTD:
validatingReader = dtdReader = new DTDValidatingReader (sourceReader, this);
+ if (specifiedResolver)
+ dtdReader.XmlResolver = resolver;
break;
case ValidationType.Schema:
-// dtdReader = new DTDValidatingReader (sourceReader, this);
-// validatingReader = new XmlSchemaValidatingReader (dtdReader, this);
-// break;
+ dtdReader = new DTDValidatingReader (sourceReader, this);
+ XsdValidatingReader xsvr = new XsdValidatingReader (dtdReader, this);
+ foreach (XmlSchema schema in Schemas)
+ xsvr.Schemas.Add (schema);
+ validatingReader = xsvr;
+ if (specifiedResolver) {
+ dtdReader.XmlResolver = resolver;
+ }
+ break;
case ValidationType.XDR:
- throw new NotImplementedException ();
+ throw new NotSupportedException ();
}
+ schemaInfo = validatingReader as IHasXmlSchemaInfo;
}
return validatingReader.Read ();
}
- [MonoTODO]
public override bool ReadAttributeValue ()
{
+ if (validatingReader == null)
+ return false;
return validatingReader.ReadAttributeValue ();
}
#if NET_1_0
- [MonoTODO]
+ // LAMESPEC: MS.NET 1.0 has critical bug here.
+ // After calling these methods, validation does not work anymore!
public override string ReadInnerXml ()
{
+ if (validatingReader == null)
+ return "";
return validatingReader.ReadInnerXml ();
}
- [MonoTODO]
public override string ReadOuterXml ()
{
+ if (validatingReader == null)
+ return "";
return validatingReader.ReadOuterXml ();
}
#endif
- [MonoTODO]
+#if NET_1_0
+ public override string ReadString ()
+ {
+ return base.ReadStringInternal ();
+ }
+#else
public override string ReadString ()
{
- return validatingReader.ReadString ();
+ return base.ReadString ();
}
+#endif
- [MonoTODO]
public object ReadTypedValue ()
{
- throw new NotImplementedException ();
+ if (dtdReader == null)
+ return null;
+ XmlSchemaDatatype dt = schemaInfo.SchemaType as XmlSchemaDatatype;
+ if (dt == null)
+ return null;
+ switch (NodeType) {
+ case XmlNodeType.Element:
+ if (IsEmptyElement)
+ return null;
+
+ storedCharacters.Length = 0;
+ bool loop = true;
+ do {
+ Read ();
+ switch (NodeType) {
+ case XmlNodeType.SignificantWhitespace:
+ case XmlNodeType.Text:
+ case XmlNodeType.CDATA:
+ storedCharacters.Append (Value);
+ break;
+ case XmlNodeType.Comment:
+ break;
+ default:
+ loop = false;
+ break;
+ }
+ } while (loop && !EOF);
+ return dt.ParseValue (storedCharacters.ToString (), NameTable, dtdReader.ParserContext.NamespaceManager);
+ case XmlNodeType.Attribute:
+ return dt.ParseValue (Value, NameTable, dtdReader.ParserContext.NamespaceManager);
+ }
+ return null;
}
public override void ResolveEntity ()