The Labs \ Source Viewer \ SSCLI \ System.Xml \ XmlAttribute

  1. //------------------------------------------------------------------------------
  2. // <copyright file="XmlAttribute.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. namespace System.Xml
  16. {
  17.     using System;
  18.     using System.Xml.Schema;
  19.     using System.Xml.XPath;
  20.     using System.Diagnostics;
  21.    
  22.     // Represents an attribute of the XMLElement object. Valid and default
  23.     // values for the attribute are defined in a DTD or schema.
  24.     public class XmlAttribute : XmlNode
  25.     {
  26.         XmlName name;
  27.         XmlLinkedNode lastChild;
  28.        
  29.         internal XmlAttribute(XmlName name, XmlDocument doc) : base(doc)
  30.         {
  31.             Debug.Assert(name != null);
  32.             Debug.Assert(doc != null);
  33.             this.parentNode = null;
  34.             if (!doc.IsLoading) {
  35.                 XmlDocument.CheckName(name.Prefix);
  36.                 XmlDocument.CheckName(name.LocalName);
  37.             }
  38.             if (name.LocalName.Length == 0)
  39.                 throw new ArgumentException(Res.GetString(Res.Xdom_Attr_Name));
  40.             this.name = name;
  41.         }
  42.        
  43.         internal int LocalNameHash {
  44.             get { return name.HashCode; }
  45.         }
  46.        
  47.         protected internal XmlAttribute(string prefix, string localName, string namespaceURI, XmlDocument doc) : this(doc.AddAttrXmlName(prefix, localName, namespaceURI, null), doc)
  48.         {
  49.         }
  50.        
  51.         internal XmlName XmlName {
  52.             get { return name; }
  53.             set { name = value; }
  54.         }
  55.        
  56.         // Creates a duplicate of this node.
  57.         public override XmlNode CloneNode(bool deep)
  58.         {
  59.             // CloneNode for attributes is deep irrespective of parameter 'deep' value
  60.             Debug.Assert(OwnerDocument != null);
  61.             XmlDocument doc = OwnerDocument;
  62.             XmlAttribute attr = doc.CreateAttribute(Prefix, LocalName, NamespaceURI);
  63.             attr.CopyChildren(doc, this, true);
  64.             return attr;
  65.         }
  66.        
  67.         // Gets the parent of this node (for nodes that can have parents).
  68.         public override XmlNode ParentNode {
  69.             get { return null; }
  70.         }
  71.        
  72.         // Gets the name of the node.
  73.         public override string Name {
  74.             get { return name.Name; }
  75.         }
  76.        
  77.         // Gets the name of the node without the namespace prefix.
  78.         public override string LocalName {
  79.             get { return name.LocalName; }
  80.         }
  81.        
  82.         // Gets the namespace URI of this node.
  83.         public override string NamespaceURI {
  84.             get { return name.NamespaceURI; }
  85.         }
  86.        
  87.         // Gets or sets the namespace prefix of this node.
  88.         public override string Prefix {
  89.             get { return name.Prefix; }
  90.             set { name = name.OwnerDocument.AddAttrXmlName(value, LocalName, NamespaceURI, SchemaInfo); }
  91.         }
  92.        
  93.         // Gets the type of the current node.
  94.         public override XmlNodeType NodeType {
  95.             get { return XmlNodeType.Attribute; }
  96.         }
  97.        
  98.         // Gets the XmlDocument that contains this node.
  99.         public override XmlDocument OwnerDocument {
  100.             get { return name.OwnerDocument; }
  101.         }
  102.        
  103.         // Gets or sets the value of the node.
  104.         public override string Value {
  105.             get { return InnerText; }
  106.             set { InnerText = value; }
  107.         }
  108.         //use InnerText which has perf optimization
  109.        
  110.         public override IXmlSchemaInfo SchemaInfo {
  111.             get { return name; }
  112.         }
  113.        
  114.         public override string InnerText {
  115.             set {
  116.                 if (PrepareOwnerElementInElementIdAttrMap()) {
  117.                     string innerText = base.InnerText;
  118.                     base.InnerText = value;
  119.                     ResetOwnerElementInElementIdAttrMap(innerText);
  120.                 }
  121.                 else {
  122.                     base.InnerText = value;
  123.                 }
  124.             }
  125.         }
  126.        
  127.         internal bool PrepareOwnerElementInElementIdAttrMap()
  128.         {
  129.             XmlDocument ownerDocument = OwnerDocument;
  130.             if (ownerDocument.DtdSchemaInfo != null) {
  131.                 // DTD exists
  132.                 XmlElement ownerElement = OwnerElement;
  133.                 if (ownerElement != null) {
  134.                     return ownerElement.Attributes.PrepareParentInElementIdAttrMap(Prefix, LocalName);
  135.                 }
  136.             }
  137.             return false;
  138.         }
  139.        
  140.         internal void ResetOwnerElementInElementIdAttrMap(string oldInnerText)
  141.         {
  142.             XmlElement ownerElement = OwnerElement;
  143.             if (ownerElement != null) {
  144.                 ownerElement.Attributes.ResetParentInElementIdAttrMap(oldInnerText, InnerText);
  145.             }
  146.         }
  147.        
  148.         internal override bool IsContainer {
  149.             get { return true; }
  150.         }
  151.        
  152.         //the function is provided only at Load time to speed up Load process
  153.         internal override XmlNode AppendChildForLoad(XmlNode newChild, XmlDocument doc)
  154.         {
  155.             XmlNodeChangedEventArgs args = doc.GetInsertEventArgsForLoad(newChild, this);
  156.            
  157.             if (args != null)
  158.                 doc.BeforeEvent(args);
  159.            
  160.             XmlLinkedNode newNode = (XmlLinkedNode)newChild;
  161.            
  162.             if (lastChild == null) {
  163.                 // if LastNode == null
  164.                 newNode.next = newNode;
  165.                 lastChild = newNode;
  166.                 newNode.SetParentForLoad(this);
  167.             }
  168.             else {
  169.                 XmlLinkedNode refNode = lastChild;
  170.                 // refNode = LastNode;
  171.                 newNode.next = refNode.next;
  172.                 refNode.next = newNode;
  173.                 lastChild = newNode;
  174.                 // LastNode = newNode;
  175.                 if (refNode.IsText && newNode.IsText) {
  176.                     NestTextNodes(refNode, newNode);
  177.                 }
  178.                 else {
  179.                     newNode.SetParentForLoad(this);
  180.                 }
  181.             }
  182.            
  183.             if (args != null)
  184.                 doc.AfterEvent(args);
  185.            
  186.             return newNode;
  187.         }
  188.        
  189.         internal override XmlLinkedNode LastNode {
  190.             get { return lastChild; }
  191.             set { lastChild = value; }
  192.         }
  193.        
  194.         internal override bool IsValidChildType(XmlNodeType type)
  195.         {
  196.             return (type == XmlNodeType.Text) || (type == XmlNodeType.EntityReference);
  197.         }
  198.        
  199.         // Gets a value indicating whether the value was explicitly set.
  200.         public virtual bool Specified {
  201.             get { return true; }
  202.         }
  203.        
  204.         public override XmlNode InsertBefore(XmlNode newChild, XmlNode refChild)
  205.         {
  206.             XmlNode node;
  207.             if (PrepareOwnerElementInElementIdAttrMap()) {
  208.                 string innerText = InnerText;
  209.                 node = base.InsertBefore(newChild, refChild);
  210.                 ResetOwnerElementInElementIdAttrMap(innerText);
  211.             }
  212.             else {
  213.                 node = base.InsertBefore(newChild, refChild);
  214.             }
  215.             return node;
  216.         }
  217.        
  218.         public override XmlNode InsertAfter(XmlNode newChild, XmlNode refChild)
  219.         {
  220.             XmlNode node;
  221.             if (PrepareOwnerElementInElementIdAttrMap()) {
  222.                 string innerText = InnerText;
  223.                 node = base.InsertAfter(newChild, refChild);
  224.                 ResetOwnerElementInElementIdAttrMap(innerText);
  225.             }
  226.             else {
  227.                 node = base.InsertAfter(newChild, refChild);
  228.             }
  229.             return node;
  230.         }
  231.        
  232.         public override XmlNode ReplaceChild(XmlNode newChild, XmlNode oldChild)
  233.         {
  234.             XmlNode node;
  235.             if (PrepareOwnerElementInElementIdAttrMap()) {
  236.                 string innerText = InnerText;
  237.                 node = base.ReplaceChild(newChild, oldChild);
  238.                 ResetOwnerElementInElementIdAttrMap(innerText);
  239.             }
  240.             else {
  241.                 node = base.ReplaceChild(newChild, oldChild);
  242.             }
  243.             return node;
  244.         }
  245.        
  246.         public override XmlNode RemoveChild(XmlNode oldChild)
  247.         {
  248.             XmlNode node;
  249.             if (PrepareOwnerElementInElementIdAttrMap()) {
  250.                 string innerText = InnerText;
  251.                 node = base.RemoveChild(oldChild);
  252.                 ResetOwnerElementInElementIdAttrMap(innerText);
  253.             }
  254.             else {
  255.                 node = base.RemoveChild(oldChild);
  256.             }
  257.             return node;
  258.         }
  259.        
  260.         public override XmlNode PrependChild(XmlNode newChild)
  261.         {
  262.             XmlNode node;
  263.             if (PrepareOwnerElementInElementIdAttrMap()) {
  264.                 string innerText = InnerText;
  265.                 node = base.PrependChild(newChild);
  266.                 ResetOwnerElementInElementIdAttrMap(innerText);
  267.             }
  268.             else {
  269.                 node = base.PrependChild(newChild);
  270.             }
  271.             return node;
  272.         }
  273.        
  274.         public override XmlNode AppendChild(XmlNode newChild)
  275.         {
  276.             XmlNode node;
  277.             if (PrepareOwnerElementInElementIdAttrMap()) {
  278.                 string innerText = InnerText;
  279.                 node = base.AppendChild(newChild);
  280.                 ResetOwnerElementInElementIdAttrMap(innerText);
  281.             }
  282.             else {
  283.                 node = base.AppendChild(newChild);
  284.             }
  285.             return node;
  286.         }
  287.        
  288.         // DOM Level 2
  289.        
  290.         // Gets the XmlElement node that contains this attribute.
  291.         public virtual XmlElement OwnerElement {
  292.             get { return parentNode as XmlElement; }
  293.         }
  294.        
  295.         // Gets or sets the markup representing just the children of this node.
  296.         public override string InnerXml {
  297.             set {
  298.                 RemoveAll();
  299.                 XmlLoader loader = new XmlLoader();
  300.                 loader.LoadInnerXmlAttribute(this, value);
  301.             }
  302.         }
  303.        
  304.         // Saves the node to the specified XmlWriter.
  305.         public override void WriteTo(XmlWriter w)
  306.         {
  307.             w.WriteStartAttribute(Prefix, LocalName, NamespaceURI);
  308.             WriteContentTo(w);
  309.             w.WriteEndAttribute();
  310.         }
  311.        
  312.         // Saves all the children of the node to the specified XmlWriter.
  313.         public override void WriteContentTo(XmlWriter w)
  314.         {
  315.             for (XmlNode node = FirstChild; node != null; node = node.NextSibling) {
  316.                 node.WriteTo(w);
  317.             }
  318.         }
  319.        
  320.         public override string BaseURI {
  321.             get {
  322.                 if (OwnerElement != null)
  323.                     return OwnerElement.BaseURI;
  324.                 return String.Empty;
  325.             }
  326.         }
  327.        
  328.         internal override void SetParent(XmlNode node)
  329.         {
  330.             this.parentNode = node;
  331.         }
  332.        
  333.         internal override XmlSpace XmlSpace {
  334.             get {
  335.                 if (OwnerElement != null)
  336.                     return OwnerElement.XmlSpace;
  337.                 return XmlSpace.None;
  338.             }
  339.         }
  340.        
  341.         internal override string XmlLang {
  342.             get {
  343.                 if (OwnerElement != null)
  344.                     return OwnerElement.XmlLang;
  345.                 return String.Empty;
  346.             }
  347.         }
  348.         internal override XPathNodeType XPNodeType {
  349.             get {
  350.                 if (IsNamespace) {
  351.                     return XPathNodeType.Namespace;
  352.                 }
  353.                 return XPathNodeType.Attribute;
  354.             }
  355.         }
  356.        
  357.         internal override string XPLocalName {
  358.             get {
  359.                 string localName = name.LocalName;
  360.                 if (localName == OwnerDocument.strXmlns)
  361.                     return string.Empty;
  362.                 return localName;
  363.             }
  364.         }
  365.        
  366.         internal bool IsNamespace {
  367.             get { return Ref.Equal(name.NamespaceURI, name.OwnerDocument.strReservedXmlns); }
  368.         }
  369.     }
  370. }

Developer Fusion