(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / System.XML / System.Xml / XmlAttribute.cs
blobd0e57109f3e9adbe74510724e4f43f55b066d39d
1 //
2 // System.Xml.XmlAttribute
3 //
4 // Authors:
5 // Jason Diamond (jason@injektilo.org)
6 // Atsushi Enomoto (ginga@kit.hi-ho.ne.jp)
7 //
8 // (C) 2002 Jason Diamond http://injektilo.org/
9 // (C) 2003 Atsushi Enomoto
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 using System;
34 using System.Text;
35 using System.Xml.XPath;
36 using Mono.Xml;
38 namespace System.Xml
40 public class XmlAttribute : XmlNode
42 #region Fields
44 private string localName;
45 private string namespaceURI;
46 private string prefix;
47 internal bool isDefault;
48 private XmlElement ownerElement;
50 #endregion
52 #region Constructor
54 protected internal XmlAttribute (
55 string prefix,
56 string localName,
57 string namespaceURI,
58 XmlDocument doc) : this (prefix, localName, namespaceURI, doc, false, true)
62 internal XmlAttribute (
63 string prefix,
64 string localName,
65 string namespaceURI,
66 XmlDocument doc,
67 bool atomizedNames, bool checkNamespace) : base (doc)
69 if (prefix == null)
70 prefix = String.Empty;
71 if (namespaceURI == null)
72 namespaceURI = String.Empty;
74 // Prefix "xml" should be also checked (http://www.w3.org/XML/xml-names-19990114-errata#NE05)
75 // but MS.NET ignores such case
76 if (checkNamespace) {
77 if (prefix == "xmlns" || (prefix == "" && localName == "xmlns"))
78 if (namespaceURI != XmlNamespaceManager.XmlnsXmlns)
79 throw new ArgumentException ("Invalid attribute namespace for namespace declaration.");
80 else if (prefix == "xml" && namespaceURI != XmlNamespaceManager.XmlnsXml)
81 throw new ArgumentException ("Invalid attribute namespace for namespace declaration.");
84 // There are no means to identify the DOM is namespace-
85 // aware or not, so we can only check Name validity.
86 if (prefix != "" && !XmlChar.IsName (prefix))
87 throw new ArgumentException ("Invalid attribute prefix.");
88 else if (!XmlChar.IsName (localName))
89 throw new ArgumentException ("Invalid attribute local name.");
91 if (atomizedNames) {
92 this.prefix = prefix;
93 this.localName = localName;
94 this.namespaceURI = namespaceURI;
95 } else {
96 this.prefix = doc.NameTable.Add (prefix);
97 this.localName = doc.NameTable.Add (localName);
98 this.namespaceURI = doc.NameTable.Add (namespaceURI);
102 #endregion
104 #region Properties
106 public override string BaseURI {
107 get { return OwnerElement != null ? OwnerElement.BaseURI : String.Empty; }
110 public override string InnerText {
111 get {
112 return base.InnerText;
115 set {
116 Value = value;
120 public override string InnerXml {
121 get {
122 // Not sure why this is an override. Passing through for now.
123 return base.InnerXml;
126 set {
127 RemoveAll ();
128 XmlNamespaceManager nsmgr = ConstructNamespaceManager ();
129 XmlParserContext ctx = new XmlParserContext (OwnerDocument.NameTable, nsmgr,
130 OwnerDocument.DocumentType != null ? OwnerDocument.DocumentType.DTD : null,
131 BaseURI, XmlLang, XmlSpace, null);
132 XmlTextReader xtr = new XmlTextReader (value, XmlNodeType.Attribute, ctx);
133 xtr.XmlResolver = OwnerDocument.Resolver;
134 xtr.Read ();
135 OwnerDocument.ReadAttributeNodeValue (xtr, this);
139 public override string LocalName {
140 get {
141 return localName;
145 public override string Name {
146 get {
147 return prefix != String.Empty ? OwnerDocument.NameTable.Add (prefix + ":" + localName) : localName;
151 public override string NamespaceURI {
152 get {
153 return namespaceURI;
157 public override XmlNodeType NodeType {
158 get {
159 return XmlNodeType.Attribute;
163 internal override XPathNodeType XPathNodeType {
164 get {
165 return XPathNodeType.Attribute;
169 public override XmlDocument OwnerDocument {
170 get {
171 return base.OwnerDocument;
175 public virtual XmlElement OwnerElement {
176 get { return ownerElement; }
179 public override XmlNode ParentNode {
180 get {
181 // It always returns null (by specification).
182 return null;
186 // We gotta do more in the set block here
187 // We need to do the proper tests and throw
188 // the correct Exceptions
190 // Wrong cases are: (1)check readonly, (2)check character validity,
191 // (3)check format validity, (4)this is attribute and qualifiedName != "xmlns"
192 public override string Prefix {
193 set {
194 if (IsReadOnly)
195 throw new XmlException ("This node is readonly.");
196 if (!XmlChar.IsNCName (value))
197 throw new ArgumentException ("Specified name is not a valid NCName: " + value);
198 if (prefix == "xmlns" && value != "xmlns")
199 throw new ArgumentException ("Cannot bind to the reserved namespace.");
201 prefix = OwnerDocument.NameTable.Add (value);
204 get {
205 return prefix;
209 public virtual bool Specified {
210 get {
211 return !isDefault;
215 private string BuildChildValue (XmlNodeList list)
217 string ret = String.Empty;
218 for (int i = 0; i < list.Count; i++) {
219 if (list [i].NodeType == XmlNodeType.EntityReference)
220 ret += BuildChildValue (list [i].ChildNodes);
221 else
222 ret += list [i].Value;
224 return ret;
227 public override string Value {
228 get { return BuildChildValue (ChildNodes); }
230 set {
231 if (this.IsReadOnly)
232 throw new ArgumentException ("Attempt to modify a read-only node.");
233 XmlNode firstChild = FirstChild;
234 if (firstChild == null)
235 AppendChild (OwnerDocument.CreateTextNode (value));
236 else if (FirstChild.NextSibling != null) {
237 this.RemoveAll ();
238 AppendChild (OwnerDocument.CreateTextNode (value));
240 else
241 firstChild.Value = value;
242 isDefault = false;
246 internal override string XmlLang {
247 get { return OwnerElement != null ? OwnerElement.XmlLang : String.Empty; }
250 internal override XmlSpace XmlSpace {
251 get { return OwnerElement != null ? OwnerElement.XmlSpace : XmlSpace.None; }
254 #endregion
256 #region Methods
258 public override XmlNode CloneNode (bool deep)
260 XmlNode node = new XmlAttribute (prefix, localName, namespaceURI,
261 OwnerDocument, true, false);
262 if (deep) {
263 for (int i = 0; i < ChildNodes.Count; i++)
264 node.AppendChild (ChildNodes [i].CloneNode (deep));
267 if (IsReadOnly)
268 node.SetReadOnly ();
269 return node;
272 internal void SetDefault ()
274 isDefault = true;
277 // Parent of XmlAttribute must be null
278 internal void SetOwnerElement (XmlElement el) {
279 ownerElement = el;
282 public override void WriteContentTo (XmlWriter w)
284 for (int i = 0; i < ChildNodes.Count; i++)
285 ChildNodes [i].WriteTo (w);
288 public override void WriteTo (XmlWriter w)
290 w.WriteStartAttribute (prefix, localName, namespaceURI);
291 WriteContentTo (w);
292 w.WriteEndAttribute ();
295 internal DTDAttributeDefinition GetAttributeDefinition ()
297 if (OwnerElement == null)
298 return null;
300 // If it is default, then directly create new attribute.
301 DTDAttListDeclaration attList = OwnerDocument.DocumentType != null ? OwnerDocument.DocumentType.DTD.AttListDecls [OwnerElement.Name] : null;
302 return attList != null ? attList [Name] : null;
304 #endregion