//
// Author:
// Duncan Mak (duncan@ximian.com)
+// Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
//
// (C) Ximian, Inc.
+// (C) Atsushi Enomoto
//
+using System;
+using System.Collections;
+using System.Xml;
+using System.Text;
+
namespace System.Xml
{
public class XmlNodeReader : XmlReader
{
+ XmlDocument document;
+ XmlNode startNode;
+ XmlNode current;
+ ReadState state = ReadState.Initial;
+ int depth;
+ bool isEndElement;
+ bool nextIsEndElement; // used for ReadString()
+ bool alreadyRead;
+ StringBuilder valueBuilder = new StringBuilder ();
+ XmlNamespaceManager defaultNsmgr;
+ Stack entityReaderStack = new Stack ();
+ XmlTextReader entityReader;
+
+ private XmlNode ownerElement {
+ get {
+ if (current.ParentNode != null && current.ParentNode.NodeType == XmlNodeType.Attribute)
+ return ((XmlAttribute) current.ParentNode).OwnerElement;
+ return (current.NodeType == XmlNodeType.Attribute) ? ((XmlAttribute)current).OwnerElement : current;
+ }
+ }
+
#region Constructor
- [MonoTODO]
public XmlNodeReader (XmlNode node)
{
+ startNode = node;
+ document = startNode.NodeType == XmlNodeType.Document ?
+ startNode as XmlDocument : startNode.OwnerDocument;
+
+ if (node.NodeType != XmlNodeType.Document
+ && node.NodeType != XmlNodeType.DocumentFragment)
+ alreadyRead = true;
+ defaultNsmgr = new XmlNamespaceManager (this.NameTable);
+
}
#endregion
#region Properties
- [MonoTODO]
public override int AttributeCount {
- get { return 0; }
+ get {
+ if (entityReader != null)
+ return entityReader.ReadState == ReadState.Interactive ?
+ entityReader.AttributeCount : 0;
+
+ if (isEndElement || current == null || current.Attributes == null)
+ return 0;
+ return ownerElement.Attributes.Count;
+ }
}
- [MonoTODO]
public override string BaseURI {
- get { return null; }
+ get {
+ if (entityReader != null && entityReader.ReadState != ReadState.Initial)
+ return entityReader.BaseURI;
+
+ if (current == null)
+ return String.Empty;
+ return current.BaseURI;
+ }
}
- [MonoTODO]
public override bool CanResolveEntity {
- get { return false; }
+ get {
+ return true;
+ }
}
- [MonoTODO]
public override int Depth {
- get { return 0; }
+ get {
+ if (entityReader != null && entityReader.ReadState == ReadState.Interactive)
+ return entityReader.Depth + depth + entityReaderStack.Count + 1;
+
+ return depth;
+ }
}
- [MonoTODO]
public override bool EOF {
- get { return false; }
+ get {
+ return this.ReadState == ReadState.EndOfFile
+ || this.ReadState == ReadState.Error;
+ }
}
- [MonoTODO]
public override bool HasAttributes {
- get { return false; }
+ get {
+ if (entityReader != null)
+ return entityReader.ReadState == ReadState.Interactive ?
+ entityReader.HasAttributes : false;
+
+ if (isEndElement || current == null)
+ return false;
+
+ if (current.Attributes == null ||
+ current.Attributes.Count == 0)
+ return false;
+ else
+ return true;
+ }
}
- [MonoTODO]
public override bool HasValue {
- get { return false; }
+ get {
+ if (entityReader != null)
+ return entityReader.ReadState == ReadState.Interactive ?
+ entityReader.IsDefault : false;
+
+ if (current == null)
+ return false;
+
+ if (current.NodeType == XmlNodeType.Element ||
+ current.NodeType == XmlNodeType.EntityReference ||
+ current.NodeType == XmlNodeType.Document ||
+ current.NodeType == XmlNodeType.DocumentFragment ||
+ current.NodeType == XmlNodeType.Notation ||
+ current.NodeType == XmlNodeType.EndElement ||
+ current.NodeType == XmlNodeType.EndEntity)
+ return false;
+ else
+ return true;
+ }
+
}
- [MonoTODO]
public override bool IsDefault {
- get { return false; }
+ get {
+ if (entityReader != null)
+ return entityReader.ReadState == ReadState.Interactive ?
+ entityReader.IsDefault : false;
+
+ if (current == null)
+ return false;
+
+ if (current.NodeType != XmlNodeType.Attribute)
+ return false;
+ else
+ {
+ return ((XmlAttribute) current).isDefault;
+ }
+ }
}
- [MonoTODO]
public override bool IsEmptyElement {
- get { return false; }
+ get {
+ if (entityReader != null)
+ return entityReader.ReadState == ReadState.Interactive ?
+ entityReader.IsDefault : false;
+
+ if (current == null)
+ return false;
+
+ if(current.NodeType == XmlNodeType.Element)
+ return ((XmlElement) current).IsEmpty;
+ else
+ return false;
+ }
}
- [MonoTODO]
public override string this [int i] {
- get { return null; }
+ get { return GetAttribute (i); }
}
- [MonoTODO]
public override string this [string name] {
- get { return null; }
+ get { return GetAttribute (name); }
}
- [MonoTODO]
public override string this [string name, string namespaceURI] {
- get { return null; }
+ get { return GetAttribute (name, namespaceURI); }
}
- [MonoTODO]
public override string LocalName {
- get { return null; }
+ get {
+ if (entityReader != null && entityReader.ReadState != ReadState.Initial)
+ return entityReader.LocalName;
+
+ if (current == null)
+ return String.Empty;
+
+ switch (current.NodeType) {
+ case XmlNodeType.Attribute:
+ case XmlNodeType.DocumentType:
+ case XmlNodeType.Element:
+ case XmlNodeType.EntityReference:
+ case XmlNodeType.ProcessingInstruction:
+ case XmlNodeType.XmlDeclaration:
+ return current.LocalName;
+ }
+
+ return String.Empty;
+ }
}
- [MonoTODO]
public override string Name {
- get { return null; }
+ get {
+ if (entityReader != null && entityReader.ReadState != ReadState.Initial)
+ return entityReader.Name;
+
+ if (current == null)
+ return String.Empty;
+
+ switch (current.NodeType) {
+ case XmlNodeType.Attribute:
+ case XmlNodeType.DocumentType:
+ case XmlNodeType.Element:
+ case XmlNodeType.EntityReference:
+ case XmlNodeType.ProcessingInstruction:
+ case XmlNodeType.XmlDeclaration:
+ return current.Name;
+ }
+
+ return String.Empty;
+ }
}
- [MonoTODO]
public override string NamespaceURI {
- get { return null; }
+ get {
+ if (entityReader != null && entityReader.ReadState != ReadState.Initial)
+ return entityReader.NamespaceURI;
+
+ if (current == null)
+ return String.Empty;
+
+ return current.NamespaceURI;
+ }
}
- [MonoTODO]
public override XmlNameTable NameTable {
- get { return null; }
+ get { return document.NameTable; }
}
- [MonoTODO]
public override XmlNodeType NodeType {
- get { return 0; }
+ get {
+ if (entityReader != null)
+ switch (entityReader.ReadState) {
+ case ReadState.Interactive:
+ return entityReader.NodeType;
+ case ReadState.Initial:
+ return XmlNodeType.EntityReference;
+ case ReadState.EndOfFile:
+ return XmlNodeType.EndEntity;
+ }
+
+ if (current == null)
+ return XmlNodeType.None;
+
+ return isEndElement ? XmlNodeType.EndElement : current.NodeType;
+ }
}
- [MonoTODO]
public override string Prefix {
- get { return null; }
+ get {
+ if (entityReader != null && entityReader.ReadState != ReadState.Initial)
+ return entityReader.Prefix;
+
+ if (current == null)
+ return String.Empty;
+
+ if (current.NodeType == XmlNodeType.Attribute)
+ return current.Prefix != String.Empty ? current.Prefix : null;
+ else
+ return current.Prefix;
+ }
}
public override char QuoteChar {
- get { return '"'; }
+ get {
+ if (entityReader != null && entityReader.ReadState != ReadState.Initial)
+ return entityReader.QuoteChar;
+
+ return '"';
+ }
}
- [MonoTODO]
public override ReadState ReadState {
- get { return 0; }
+ get { return state; }
}
- [MonoTODO]
public override string Value {
- get { return null; }
+ get {
+ if (entityReader != null && entityReader.ReadState != ReadState.Initial)
+ return entityReader.Value;
+
+ if (NodeType == XmlNodeType.DocumentType)
+ return ((XmlDocumentType) current).InternalSubset;
+ else
+ return HasValue ? current.Value : String.Empty;
+ }
}
- [MonoTODO]
public override string XmlLang {
- get { return null; }
+ get {
+ if (entityReader != null && entityReader.ReadState != ReadState.Initial)
+ return entityReader.XmlLang;
+
+ if (current == null)
+ return String.Empty;
+
+ return current.XmlLang;
+ }
}
- [MonoTODO]
public override XmlSpace XmlSpace {
- get { return 0; }
+ get {
+ if (entityReader != null && entityReader.ReadState != ReadState.Initial)
+ return entityReader.XmlSpace;
+
+ if (current == null)
+ return XmlSpace.None;
+
+ return current.XmlSpace;
+ }
}
#endregion
#region Methods
- [MonoTODO]
+ // If current entityReference is a child of an attribute,
+ // then MoveToAttribute simply means that we no more need this entity reader.
+ // Otherwise, this invokation means that
+ // it is expected to move to resolved (maybe) element's attribute.
+ //
+ // This rule applies to many methods like MoveTo*Attribute().
+ private bool CheckAndResetEntityReaderOnMoveToAttribute ()
+ {
+ if (entityReader == null)
+ return false;
+
+ if (current != null && current.ParentNode != null &&
+ current.ParentNode.NodeType == XmlNodeType.Attribute) {
+ entityReader.Close ();
+ entityReader = entityReaderStack.Count > 0 ?
+ entityReaderStack.Pop () as XmlTextReader : null;
+ return true;
+ }
+ else
+ return false;
+ }
+
public override void Close ()
{
+ if (entityReader != null)
+ entityReader.Close ();
+ while (entityReaderStack.Count > 0)
+ ((XmlTextReader) entityReaderStack.Pop ()).Close ();
+
+ current = null;
+ state = ReadState.Closed;
}
- [MonoTODO]
public override string GetAttribute (int attributeIndex)
{
- return null;
+ if (entityReader != null && entityReader.ReadState != ReadState.Initial)
+ return entityReader.GetAttribute (attributeIndex);
+
+ if (NodeType == XmlNodeType.XmlDeclaration) {
+ XmlDeclaration decl = current as XmlDeclaration;
+ if (attributeIndex == 0)
+ return decl.Version;
+ else if (attributeIndex == 1) {
+ if (decl.Encoding != String.Empty)
+ return decl.Encoding;
+ else if (decl.Standalone != String.Empty)
+ return decl.Standalone;
+ }
+ else if (attributeIndex == 2 &&
+ decl.Encoding != String.Empty && decl.Standalone != null)
+ return decl.Standalone;
+ throw new ArgumentOutOfRangeException ("Index out of range.");
+ } else if (NodeType == XmlNodeType.DocumentType) {
+ XmlDocumentType doctype = current as XmlDocumentType;
+ if (attributeIndex == 0) {
+ if (doctype.PublicId != "")
+ return doctype.PublicId;
+ else if (doctype.SystemId != "")
+ return doctype.SystemId;
+ } else if (attributeIndex == 1)
+ if (doctype.PublicId == "" && doctype.SystemId != "")
+ return doctype.SystemId;
+ throw new ArgumentOutOfRangeException ("Index out of range.");
+ }
+
+ // This is MS.NET bug which returns attributes in spite of EndElement.
+ if (isEndElement || current == null)
+ return null;
+
+ if (attributeIndex < 0 || attributeIndex > AttributeCount)
+ throw new ArgumentOutOfRangeException ("Index out of range.");
+
+ return ownerElement.Attributes [attributeIndex].Value;
}
- [MonoTODO]
public override string GetAttribute (string name)
{
- return null;
+ if (entityReader != null && entityReader.ReadState != ReadState.Initial)
+ return entityReader.GetAttribute (name);
+
+ // This is MS.NET bug which returns attributes in spite of EndElement.
+ if (isEndElement || current == null)
+ return null;
+
+ if (NodeType == XmlNodeType.XmlDeclaration)
+ return GetXmlDeclarationAttribute (name);
+ else if (NodeType == XmlNodeType.DocumentType)
+ return GetDocumentTypeAttribute (name);
+
+ XmlAttribute attr = ownerElement.Attributes [name];
+ if (attr == null)
+ return null;
+ else
+ return attr.Value;
}
- [MonoTODO]
public override string GetAttribute (string name, string namespaceURI)
{
+ if (entityReader != null && entityReader.ReadState != ReadState.Initial)
+ return entityReader.GetAttribute (name, namespaceURI);
+
+ // This is MS.NET bug which returns attributes in spite of EndElement.
+ if (isEndElement || current == null)
+ return null;
+
+ if (NodeType == XmlNodeType.XmlDeclaration)
+ return GetXmlDeclarationAttribute (name);
+ else if (NodeType == XmlNodeType.DocumentType)
+ return GetDocumentTypeAttribute (name);
+
+ XmlAttribute attr = ownerElement.Attributes [name, namespaceURI];
+ if (attr == null)
+ return null; // In fact MS.NET returns null instead of String.Empty.
+ else
+ return attr.Value;
+ }
+
+ private string GetXmlDeclarationAttribute (string name)
+ {
+ XmlDeclaration decl = current as XmlDeclaration;
+ switch (name) {
+ case "version":
+ return decl.Version;
+ case "encoding":
+ // This is MS.NET bug that XmlNodeReturns in case of string.empty.
+ return decl.Encoding != String.Empty ? decl.Encoding : null;
+ case "standalone":
+ return decl.Standalone;
+ }
return null;
}
- [MonoTODO]
- public override string LookupNamespace (string prefix)
+ private string GetDocumentTypeAttribute (string name)
{
+ XmlDocumentType doctype = current as XmlDocumentType;
+ switch (name) {
+ case "PUBLIC":
+ return doctype.PublicId;
+ case "SYSTEM":
+ return doctype.SystemId;
+ }
return null;
}
- [MonoTODO]
+ internal XmlParserContext GetInternalParserContext ()
+ {
+ if (entityReader != null)
+ return entityReader.GetInternalParserContext ();
+ else
+ return new XmlParserContext (document.NameTable,
+ current.ConstructNamespaceManager (),
+ document.DocumentType != null ? document.DocumentType.DTD : null,
+ current.BaseURI, XmlLang, XmlSpace, Encoding.Unicode);
+ }
+
+ public override string LookupNamespace (string prefix)
+ {
+ if (entityReader != null && entityReader.ReadState != ReadState.Initial)
+ return entityReader.LookupNamespace (prefix);
+
+ if (current == null)
+ return null;
+
+ XmlAttribute curAttr = current as XmlAttribute;
+ XmlNode target = curAttr != null ? curAttr.OwnerElement : current;
+
+ if (prefix == "") {
+ do {
+ XmlAttribute attr = target.Attributes ["xmlns"];
+ if (attr != null)
+ return attr.Value;
+ target = target.ParentNode;
+ } while (target.NodeType != XmlNodeType.Document);
+ } else {
+ string name = "xmlns:" + prefix;
+ do {
+ XmlAttribute attr = target.Attributes [name];
+ if (attr != null)
+ return attr.Value;
+ target = target.ParentNode;
+ } while (target.NodeType != XmlNodeType.Document);
+ }
+ return defaultNsmgr.LookupNamespace (prefix);
+ }
+
public override void MoveToAttribute (int attributeIndex)
{
+ if (entityReader != null) {
+ if (!this.CheckAndResetEntityReaderOnMoveToAttribute ()) {
+ entityReader.MoveToAttribute (attributeIndex);
+ return;
+ }
+ // And in case of abondoning entityReader, go on...
+ }
+
+ if (isEndElement || attributeIndex < 0 || attributeIndex > AttributeCount)
+ throw new ArgumentOutOfRangeException ();
+
+ state = ReadState.Interactive;
+ current = ownerElement.Attributes [attributeIndex];
}
- [MonoTODO]
public override bool MoveToAttribute (string name)
{
- return false;
+ if (entityReader != null) {
+ if (!this.CheckAndResetEntityReaderOnMoveToAttribute ())
+ return entityReader.MoveToAttribute (name);
+ // And in case of abondoning entityReader, go on...
+ }
+
+ if (isEndElement || current == null)
+ return false;
+ XmlNode tmpCurrent = current;
+ if (current.ParentNode.NodeType == XmlNodeType.Attribute)
+ current = current.ParentNode;
+
+ XmlAttribute attr = ownerElement.Attributes [name];
+ if (attr == null) {
+ current = tmpCurrent;
+ return false;
+ }
+ else {
+ current = attr;
+ return true;
+ }
}
- [MonoTODO]
public override bool MoveToAttribute (string name, string namespaceURI)
{
- return false;
+ if (entityReader != null) {
+ if (!this.CheckAndResetEntityReaderOnMoveToAttribute ())
+ return entityReader.MoveToAttribute (name, namespaceURI);
+ // And in case of abondoning entityReader, go on...
+ }
+
+ if (isEndElement || current == null)
+ return false;
+
+ XmlAttribute attr = ownerElement.Attributes [name, namespaceURI];
+ if (attr == null)
+ return false;
+ else {
+ current = attr;
+ return true;
+ }
+ }
+
+ private void MoveToParentElement ()
+ {
+ // This is buggy. It is not only the case when EndElement = true.
+ isEndElement = true;
+ depth--;
+ current = current.ParentNode;
}
- [MonoTODO]
public override bool MoveToElement ()
{
- return false;
+ if (entityReader != null) {
+ if (!this.CheckAndResetEntityReaderOnMoveToAttribute ())
+ return entityReader.MoveToElement ();
+ // And in case of abondoning entityReader, go on...
+ }
+
+ if (current == null)
+ return false;
+ if (current.NodeType == XmlNodeType.Attribute) {
+ current = ((XmlAttribute) current).OwnerElement;
+ return true;
+ } else
+ return false;
}
- [MonoTODO]
public override bool MoveToFirstAttribute ()
{
- return false;
+ if (entityReader != null) {
+ if (!this.CheckAndResetEntityReaderOnMoveToAttribute ())
+ return entityReader.MoveToFirstAttribute ();
+ // And in case of abondoning entityReader, go on...
+ }
+
+ if (current == null)
+ return false;
+
+ if(ownerElement.Attributes.Count > 0)
+ {
+ current = ownerElement.Attributes [0];
+ return true;
+ }
+ else
+ return false;
}
- [MonoTODO]
public override bool MoveToNextAttribute ()
{
- return false;
+ if (entityReader != null) {
+ if (!this.CheckAndResetEntityReaderOnMoveToAttribute ())
+ return entityReader.MoveToNextAttribute ();
+ // And in case of abondoning entityReader, go on...
+ }
+
+ if (current == null)
+ return false;
+
+ if (current.NodeType != XmlNodeType.Attribute)
+ return MoveToFirstAttribute ();
+ else
+ {
+ XmlAttributeCollection ac = ((XmlAttribute) current).OwnerElement.Attributes;
+ for (int i=0; i<ac.Count-1; i++)
+ {
+ XmlAttribute attr = ac [i];
+ if (attr == current)
+ {
+ i++;
+ if (i == ac.Count)
+ return false;
+ current = ac [i];
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
+ private bool MoveToNextSibling ()
+ {
+ if (nextIsEndElement) {
+ // nextIsEndElement is set only by ReadString.
+ nextIsEndElement = false;
+ MoveToParentElement ();
+ } else if (alreadyRead) {
+ alreadyRead = false;
+ return current != null;
+ }
+ if (current.NextSibling != null) {
+ isEndElement = false;
+ current = current.NextSibling;
+ } else {
+ MoveToParentElement ();
+ }
+ if (current == null) {
+ state = ReadState.EndOfFile;
+ return false;
+ }
+ else
+ return true;
}
- [MonoTODO]
public override bool Read ()
{
- return false;
+ if (EOF)
+ return false;
+
+ this.CheckAndResetEntityReaderOnMoveToAttribute ();
+ if (entityReader != null) {
+ // Read finalizes entity reader.
+ switch (entityReader.ReadState) {
+ case ReadState.Interactive:
+ case ReadState.Initial:
+ // If it is ended, then other properties/methods will take care.
+ entityReader.Read ();
+ return true;
+ default:
+ entityReader = entityReaderStack.Count > 0 ?
+ entityReaderStack.Pop () as XmlTextReader : null;
+ return Read ();
+ }
+ // and go on ...
+ }
+
+ if (ReadState == ReadState.Initial) {
+ current = startNode;
+ state = ReadState.Interactive;
+ // when startNode is document or fragment
+ if (!alreadyRead)
+ current = startNode.FirstChild;
+ else
+ alreadyRead = false;
+ if (current == null) {
+ state = ReadState.Error;
+ return false;
+ } else
+ return true;
+ }
+
+ MoveToElement ();
+
+ if (IsEmptyElement || isEndElement) {
+ // Then go up and move to next.
+ // If no more nodes, then set EOF.
+ isEndElement = false;
+ if (current.ParentNode == null
+ || current.ParentNode.NodeType == XmlNodeType.Document
+ || current.ParentNode.NodeType == XmlNodeType.DocumentFragment) {
+ current = null;
+ state = ReadState.EndOfFile;
+ return false;
+ } else if (current.NextSibling == null) {
+ depth--;
+ current = current.ParentNode;
+ isEndElement = true;
+ return true;
+ } else {
+ current = current.NextSibling;
+ return true;
+ }
+
+ } else if (nextIsEndElement) {
+ // nextIsEndElement is set only by ReadString.
+ nextIsEndElement = false;
+ isEndElement = true;
+ return current != null;
+
+ } else if (alreadyRead) {
+ alreadyRead = false;
+ return current != null;
+ }
+
+ if (!isEndElement && current.FirstChild != null) {
+ isEndElement = false;
+ current = current.FirstChild;
+ depth++;
+ } else if (current.NodeType == XmlNodeType.Element) {
+ isEndElement = true;
+ if (current.FirstChild != null)
+ depth--;
+ } else
+ MoveToNextSibling ();
+
+ return current != null;
}
- [MonoTODO]
public override bool ReadAttributeValue ()
{
- return false;
- }
-
- [MonoTODO]
+ if (entityReader != null) {
+ switch (entityReader.ReadState) {
+ case ReadState.Interactive:
+ case ReadState.Initial:
+ // If it is ended, then other properties/methods will take care.
+ return entityReader.ReadAttributeValue ();
+ default:
+ entityReader = entityReaderStack.Count > 0 ?
+ entityReaderStack.Pop () as XmlTextReader : null;
+ // and go on ...
+ return ReadAttributeValue ();
+ }
+ }
+
+ if (current.NodeType == XmlNodeType.Attribute) {
+ if (current.FirstChild == null)
+ return false;
+ current = current.FirstChild;
+ return true;
+ } else if (current.ParentNode.NodeType == XmlNodeType.Attribute) {
+ if (current.NextSibling == null)
+ return false;
+ current = current.NextSibling;
+ return true;
+ } else
+ return false;
+ }
+
+#if NET_1_0
+ // Its traversal behavior is almost same as Read().
public override string ReadInnerXml ()
{
- return null;
- }
-
- [MonoTODO]
+ if (entityReader != null) {
+ if (entityReader.EOF) {
+ entityReader = entityReaderStack.Count > 0 ?
+ entityReaderStack.Pop () as XmlTextReader : null;
+ return ReadInnerXml ();
+ } else
+ return entityReader.ReadInnerXml ();
+ }
+
+ if (this.state != ReadState.Interactive)
+ return String.Empty;
+
+ XmlNode initial = current;
+ // Almost copied from XmlTextReader.
+ switch (NodeType) {
+ case XmlNodeType.Attribute:
+ return Value;
+ case XmlNodeType.Element:
+ if (IsEmptyElement)
+ return String.Empty;
+
+ int startDepth = depth;
+
+ bool loop = true;
+ do {
+ Read ();
+ if (NodeType ==XmlNodeType.None)
+ throw new XmlException ("unexpected end of xml.");
+ else if (NodeType == XmlNodeType.EndElement && depth == startDepth) {
+ loop = false;
+ Read ();
+ }
+ } while (loop);
+ return initial.InnerXml;
+ case XmlNodeType.None:
+ return String.Empty;
+ default:
+ Read ();
+ return String.Empty;
+ }
+ }
+
+ // Its traversal behavior is almost same as Read().
public override string ReadOuterXml ()
{
- return null;
- }
+ if (entityReader != null) {
+ if (entityReader.EOF) {
+ entityReader = entityReaderStack.Count > 0 ?
+ entityReaderStack.Pop () as XmlTextReader : null;
+ return ReadOuterXml ();
+ } else
+ return entityReader.ReadOuterXml ();
+ }
+
+ if (NodeType == XmlNodeType.EndElement)
+ return String.Empty;
+ XmlNode initial = current;
+
+ switch (NodeType) {
+ case XmlNodeType.Attribute:
+ return current.OuterXml;
+ case XmlNodeType.Element:
+ if (NodeType == XmlNodeType.Element && !IsEmptyElement)
+ ReadInnerXml ();
+ else
+ Read ();
+ return initial.OuterXml;
+ case XmlNodeType.None:
+ return String.Empty;
+ default:
+ Read ();
+ return String.Empty;
+ }
+ }
+#endif
- [MonoTODO]
public override string ReadString ()
{
- return null;
+ return ReadStringInternal ();
}
- [MonoTODO]
public override void ResolveEntity ()
{
+ if (NodeType != XmlNodeType.EntityReference)
+ throw new InvalidOperationException ("The current node is not an Entity Reference");
+ XmlEntity entity = document.DocumentType != null ?
+ document.DocumentType.Entities.GetNamedItem (Name) as XmlEntity : null;
+
+ // MS.NET seems simply ignoring undeclared entity reference ;-(
+ string replacementText =
+ (entity != null) ? entity.InnerText : String.Empty;
+
+ XmlNodeType xmlReaderNodeType =
+ (current.ParentNode != null && current.ParentNode.NodeType == XmlNodeType.Attribute) ?
+ XmlNodeType.Attribute : XmlNodeType.Element;
+
+ XmlParserContext ctx = null;
+ if (entityReader != null) {
+ entityReaderStack.Push (entityReader);
+ ctx = entityReader.GetInternalParserContext ();
+ }
+ if (ctx == null) {
+ ctx = new XmlParserContext (document.NameTable,
+ current.ConstructNamespaceManager (),
+ document.DocumentType != null ? document.DocumentType.DTD : null,
+ BaseURI, XmlLang, XmlSpace, Encoding.Unicode);
+ }
+ entityReader = new XmlTextReader (replacementText, xmlReaderNodeType, ctx);
+ entityReader.XmlResolver = document.Resolver;
+ entityReader.MaybeTextDecl = true;
}
- [MonoTODO]
public override void Skip ()
{
+ // Why is this overriden? Such skipping might raise
+ // (or ignore) unexpected validation error.
+ base.Skip ();
}
#endregion
}