-// -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
//
// System.Xml.XmlAttribute
//
// Author:
-// Daniel Weber (daniel-weber@austin.rr.com)
+// Jason Diamond (jason@injektilo.org)
+//
+// (C) 2002 Jason Diamond http://injektilo.org/
//
-// (C) 2001 Daniel Weber
using System;
+using System.Text;
+using System.Xml.XPath;
namespace System.Xml
{
- /// <summary>
- /// Summary description for XmlAttribute.
- /// </summary>
public class XmlAttribute : XmlNode
{
- // ============ private data structures ==============================
- private XmlNode FOwnerElement;
-
- string FattrName;
- string FattrValue;
-
- //==== Public Properties ====================================================
+ #region Fields
+
+ private XmlLinkedNode lastChild;
+ private string localName;
+ private string namespaceURI;
+ private string prefix;
+ internal bool isDefault;
+ private XmlElement ownerElement;
- /// <summary>
- /// Returns the local name of the attribute. For attributes, this is the same as Name
- /// </summary>
- public override string LocalName
+ #endregion
+
+ #region Constructor
+
+ [MonoTODO("need to set namespaceURI if prefix is recognized built-in ones like xmlns")]
+ protected internal XmlAttribute (
+ string prefix,
+ string localName,
+ string namespaceURI,
+ XmlDocument doc) : base (doc)
{
- get
- {
- return FattrName;
+ // What to be recognized is: xml:space, xml:lang, xml:base, and
+ // xmlns and xmlns:* (when XmlDocument.Namespaces = true only)
+ this.prefix = prefix;
+ this.localName = localName;
+ this.namespaceURI = namespaceURI;
+ }
+
+ #endregion
+
+ #region Properties
+
+ public override string BaseURI {
+ get {
+ return OwnerElement.BaseURI;
}
}
- /// <summary>
- /// Get the qualified attribute name. Attributes do not have an associated namespace.
- /// </summary>
- public override string Name
- {
- get
- {
- return FattrName;
+ public override string InnerText {
+ get {
+ StringBuilder builder = new StringBuilder ();
+ AppendChildValues (this, builder);
+ return builder.ToString ();
+ }
+
+ set {
+ Value = value;
}
}
- /// <summary>
- /// Override. Returns the node type.
- /// </summary>
- public override XmlNodeType NodeType
+ private void AppendChildValues (XmlNode parent, StringBuilder builder)
{
- get
- {
+ XmlNode node = parent.FirstChild;
+
+ while (node != null) {
+ builder.Append (node.Value);
+ AppendChildValues (node, builder);
+ node = node.NextSibling;
+ }
+ }
+
+ [MonoTODO ("Setter is incomplete(XmlTextReader.ReadAttribute is incomplete;No resolution for xml:lang/space")]
+ public override string InnerXml {
+ get {
+ // Not sure why this is an override. Passing through for now.
+ return base.InnerXml;
+ }
+
+ set {
+ XmlNamespaceManager nsmgr = ConstructNamespaceManager ();
+ XmlParserContext ctx = new XmlParserContext (OwnerDocument.NameTable, nsmgr, XmlLang, this.XmlSpace);
+ XmlTextReader xtr = OwnerDocument.ReusableReader;
+ xtr.SetReaderContext (BaseURI, ctx);
+ xtr.SetReaderFragment (new System.IO.StringReader ("'" + value.Replace ("'", "'") + "'"), XmlNodeType.Attribute);
+
+ OwnerDocument.ReadAttributeNodeValue (xtr, this);
+ }
+ }
+
+ public override string LocalName {
+ get {
+ return localName;
+ }
+ }
+
+ public override string Name {
+ get {
+ return prefix != String.Empty ? prefix + ":" + localName : localName;
+ }
+ }
+
+ public override string NamespaceURI {
+ get {
+ return namespaceURI;
+ }
+ }
+
+ public override XmlNodeType NodeType {
+ get {
return XmlNodeType.Attribute;
}
}
- /// <summary>
- /// Retrieve the XmlElement owner of this attribute, or null if attribute not assigned
- /// </summary>
- public virtual XmlElement OwnerElement
- {
- get
- {
- if (FOwnerElement.NodeType == XmlNodeType.Element)
- return FOwnerElement as XmlElement;
- else
- return null;
+ internal override XPathNodeType XPathNodeType {
+ get {
+ return XPathNodeType.Attribute;
}
}
- /// <summary>
- /// Get/Set the value for this node
- /// </summary>
- public override string Value
- {
- get
- {
- return FattrValue;
+ public override XmlDocument OwnerDocument {
+ get {
+ return base.OwnerDocument;
+ }
+ }
+
+ public virtual XmlElement OwnerElement {
+ get {
+ return ownerElement;
+ }
+ }
+
+ public override XmlNode ParentNode {
+ get {
+ // It always returns null (by specification).
+ return null;
+ }
+ }
+
+ [MonoTODO("setter incomplete (name character check, format check, wrong prefix&nsURI)")]
+ // We gotta do more in the set block here
+ // We need to do the proper tests and throw
+ // the correct Exceptions
+ //
+ // Wrong cases are: (1)check readonly, (2)check character validity,
+ // (3)check format validity, (4)this is attribute and qualifiedName != "xmlns"
+ // (5)when argument is 'xml' or 'xmlns' and namespaceURI doesn't match
+ public override string Prefix {
+ set {
+ if(IsReadOnly)
+ throw new XmlException ("This node is readonly.");
+
+ XmlNamespaceManager nsmgr = ConstructNamespaceManager ();
+ string nsuri = nsmgr.LookupNamespace (value);
+ if(nsuri == null)
+ throw new XmlException ("Namespace URI not found for this prefix");
+
+ prefix = value;
}
- set
- {
- FattrValue = value;
+ get {
+ return prefix;
+ }
+ }
+
+ [MonoTODO("There are no code which sets 'specified = true', so this logic is without checking.")]
+ public virtual bool Specified {
+ get {
+ return !isDefault;
}
}
- //============== Public Methods =============================================
+ public override string Value {
+ get {
+ XmlNode firstChild = FirstChild;
+ if (firstChild == null)
+ return String.Empty;
+ return firstChild.Value;
+ }
- /// <summary>
- /// Return a clone of the node
- /// </summary>
- /// <param name="deep">Make copy of all children</param>
- /// <returns>Cloned node</returns>
- public override XmlNode CloneNode( bool deep)
- {
- // TODO - implement XmlAttribute.CloneNode()
- throw new NotImplementedException();
+ set {
+ XmlNode firstChild = FirstChild;
+ if (firstChild == null)
+ AppendChild (OwnerDocument.CreateTextNode (value));
+ else
+ firstChild.Value = value;
+ }
}
- /// <summary>
- /// Saves all children of the current node to the passed writer
- /// </summary>
- /// <param name="w"></param>
- public override void WriteContentTo(XmlWriter w)
- {
- // TODO - implement XmlAttribute.WriteContentsTo(XmlWriter)
- throw new NotImplementedException();
+ internal override string XmlLang {
+ get { return OwnerElement.XmlLang; }
}
- /// <summary>
- /// Saves the current node to writer w
- /// </summary>
- /// <param name="w"></param>
- public override void WriteTo(XmlWriter w)
- {
- // TODO - implement XmlAttribute.WriteTo(XmlWriter)
- throw new NotImplementedException();
+ internal override XmlSpace XmlSpace {
+ get { return OwnerElement.XmlSpace; }
}
- // ============ Internal methods ====================================
- internal void setOwnerElement( XmlElement newOwnerElement)
+ #endregion
+
+ #region Methods
+
+ public override XmlNode CloneNode (bool deep)
{
- FOwnerElement = newOwnerElement;
+ XmlNode node = new XmlAttribute (prefix, localName, namespaceURI,
+ OwnerDocument);
+ if (deep) {
+ while ((node != null) && (node.HasChildNodes)) {
+ AppendChild (node.NextSibling.CloneNode (true));
+ node = node.NextSibling;
+ }
+ }
+
+ return node;
}
- // ============ Constructors =========================================
- internal XmlAttribute ( XmlDocument aOwner, // owner document
- string attributeName, // cannot be ""
- string attValue) : base(aOwner)
+ // Parent of XmlAttribute must be null
+ internal void SetOwnerElement (XmlElement el) {
+ ownerElement = el;
+ }
+
+ public override void WriteContentTo (XmlWriter w)
{
- if (aOwner == null)
- throw new ArgumentException("Null OwnerDocument passed to XmlAttribute constructor");
- if (attributeName.Length == 0)
- throw new ArgumentException("Empty string passed to XmlAttribute constructor");
+ w.WriteString (Value);
+ }
- FOwnerElement = null;
- FattrName = attributeName;
- FattrValue = attValue;
+ public override void WriteTo (XmlWriter w)
+ {
+ w.WriteAttributeString (prefix, localName, namespaceURI, Value);
}
-
+ #endregion
+
+ internal override XmlLinkedNode LastLinkedChild {
+ get { return lastChild; }
+
+ set { lastChild = value; }
+ }
}
}