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

  1. //------------------------------------------------------------------------------
  2. // <copyright file="XmlEntityReference.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. // <code>EntityReference</code> objects may be inserted into the structure
  16. // model when an entity reference is in the source document, or when the user
  17. // wishes to insert an entity reference. Note that character references and
  18. // references to predefined entities are considered to be expanded by the
  19. // HTML or XML processor so that characters are represented by their Unicode
  20. // equivalent rather than by an entity reference. Moreover, the XML
  21. // processor may completely expand references to entities while building the
  22. // structure model, instead of providing <code>EntityReference</code>
  23. // objects. If it does provide such objects, then for a given
  24. // <code>EntityReference</code> node, it may be that there is no
  25. // <code>Entity</code> node representing the referenced entity; but if such
  26. // an <code>Entity</code> exists, then the child list of the
  27. // <code>EntityReference</code> node is the same as that of the
  28. // <code>Entity</code> node. As with the <code>Entity</code> node, all
  29. // descendants of the <code>EntityReference</code> are readonly.
  30. // <p>The resolution of the children of the <code>EntityReference</code> (the
  31. // replacement value of the referenced <code>Entity</code>) may be lazily
  32. // evaluated; actions by the user (such as calling the
  33. // <code>childNodes</code> method on the <code>EntityReference</code> node)
  34. // are assumed to trigger the evaluation.
  35. namespace System.Xml
  36. {
  37.    
  38.     using System.Diagnostics;
  39.    
  40.     // Represents an entity reference node.
  41.     public class XmlEntityReference : XmlLinkedNode
  42.     {
  43.         string name;
  44.         XmlLinkedNode lastChild;
  45.        
  46.         protected internal XmlEntityReference(string name, XmlDocument doc) : base(doc)
  47.         {
  48.             if (!doc.IsLoading) {
  49.                 if (name.Length > 0 && name[0] == '#') {
  50.                     throw new ArgumentException(Res.GetString(Res.Xdom_InvalidCharacter_EntityReference));
  51.                 }
  52.             }
  53.             this.name = doc.NameTable.Add(name);
  54.             doc.fEntRefNodesPresent = true;
  55.         }
  56.        
  57.         // Gets the name of the node.
  58.         public override string Name {
  59.             get { return name; }
  60.         }
  61.        
  62.         // Gets the name of the node without the namespace prefix.
  63.         public override string LocalName {
  64.             get { return name; }
  65.         }
  66.        
  67.         // Gets or sets the value of the node.
  68.         public override string Value {
  69.             get { return null; }
  70.            
  71.             set {
  72.                 throw new InvalidOperationException(Res.GetString(Res.Xdom_EntRef_SetVal));
  73.             }
  74.         }
  75.        
  76.         // Gets the type of the node.
  77.         public override XmlNodeType NodeType {
  78.             get { return XmlNodeType.EntityReference; }
  79.         }
  80.        
  81.         // Creates a duplicate of this node.
  82.         public override XmlNode CloneNode(bool deep)
  83.         {
  84.             Debug.Assert(OwnerDocument != null);
  85.             XmlEntityReference eref = OwnerDocument.CreateEntityReference(name);
  86.             return eref;
  87.         }
  88.        
  89.         //
  90.         // Microsoft extensions
  91.         //
  92.        
  93.         // Gets a value indicating whether the node is read-only.
  94.         public override bool IsReadOnly {
  95.                 // Make entity references readonly
  96.             get { return true; }
  97.         }
  98.        
  99.         internal override bool IsContainer {
  100.             get { return true; }
  101.         }
  102.        
  103.         internal override void SetParent(XmlNode node)
  104.         {
  105.             base.SetParent(node);
  106.             if (LastNode == null && node != null && node != OwnerDocument) {
  107.                 //first time insert the entity reference into the tree, we should expand its children now
  108.                 XmlLoader loader = new XmlLoader();
  109.                 loader.ExpandEntityReference(this);
  110.                
  111.             }
  112.         }
  113.        
  114.         internal override void SetParentForLoad(XmlNode node)
  115.         {
  116.             this.SetParent(node);
  117.         }
  118.        
  119.         internal override XmlLinkedNode LastNode {
  120.             get { return lastChild; }
  121.             set { lastChild = value; }
  122.         }
  123.        
  124.         internal override bool IsValidChildType(XmlNodeType type)
  125.         {
  126.             switch (type) {
  127.                 case XmlNodeType.Element:
  128.                 case XmlNodeType.Text:
  129.                 case XmlNodeType.EntityReference:
  130.                 case XmlNodeType.Comment:
  131.                 case XmlNodeType.Whitespace:
  132.                 case XmlNodeType.SignificantWhitespace:
  133.                 case XmlNodeType.ProcessingInstruction:
  134.                 case XmlNodeType.CDATA:
  135.                     return true;
  136.                 default:
  137.                    
  138.                     return false;
  139.             }
  140.         }
  141.        
  142.         // Saves the node to the specified XmlWriter.
  143.         public override void WriteTo(XmlWriter w)
  144.         {
  145.             w.WriteEntityRef(name);
  146.         }
  147.        
  148.         // Saves all the children of the node to the specified XmlWriter.
  149.         public override void WriteContentTo(XmlWriter w)
  150.         {
  151.             // -- eventually will the fix. commented out waiting for finalizing on the issue.
  152.             foreach (XmlNode n in this) {
  153.                 n.WriteTo(w);
  154.             }
  155.             //still use the old code to generate the output
  156.             /*
  157.             foreach( XmlNode n in this ) {
  158.                 if ( n.NodeType != XmlNodeType.EntityReference )
  159.                 n.WriteTo( w );
  160.                 else
  161.                     n.WriteContentTo( w );
  162.             }*/        }
  163.        
  164.         public override string BaseURI {
  165.             get { return OwnerDocument.BaseURI; }
  166.         }
  167.        
  168.         private string ConstructBaseURI(string baseURI, string systemId)
  169.         {
  170.             if (baseURI == null)
  171.                 return systemId;
  172.             int nCount = baseURI.LastIndexOf('/') + 1;
  173.             string buf = baseURI;
  174.             if (nCount > 0 && nCount < baseURI.Length)
  175.                 buf = baseURI.Substring(0, nCount);
  176.             else if (nCount == 0)
  177.                 buf = buf + "\\";
  178.             return (buf + systemId.Replace('\\', '/'));
  179.         }
  180.        
  181.         //childrenBaseURI returns where the entity reference node's children come from
  182.         internal string ChildBaseURI {
  183.             get {
  184.                 //get the associate entity and return its baseUri
  185.                 XmlEntity ent = OwnerDocument.GetEntityNode(name);
  186.                 if (ent != null) {
  187.                     if (ent.SystemId != null && ent.SystemId.Length > 0)
  188.                         return ConstructBaseURI(ent.BaseURI, ent.SystemId);
  189.                     else
  190.                         return ent.BaseURI;
  191.                 }
  192.                 return String.Empty;
  193.             }
  194.         }
  195.     }
  196. }

Developer Fusion