File: XmlDocumentFragment.cs

package info (click to toggle)
mono 6.14.1%2Bds2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,282,732 kB
  • sloc: cs: 11,182,461; xml: 2,850,281; ansic: 699,123; cpp: 122,919; perl: 58,604; javascript: 30,841; asm: 21,845; makefile: 19,602; sh: 10,973; python: 4,772; pascal: 925; sql: 859; sed: 16; php: 1
file content (176 lines) | stat: -rw-r--r-- 7,605 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
//------------------------------------------------------------------------------
// <copyright file="XmlDocumentFragment.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
// <owner current="true" primary="true">Microsoft</owner>
//------------------------------------------------------------------------------

// <code>DocumentFragment</code> is a "lightweight" or "minimal" 
// <code>Document</code> object. It is very common to want to be able to 
// extract a portion of a document's tree or to create a new fragment of a 
// document. Imagine implementing a user command like cut or rearranging a 
// document by moving fragments around. It is desirable to have an object 
// which can hold such fragments and it is quite natural to use a Node for 
// this purpose. While it is true that a <code>Document</code> object could 
// fulfil this role,  a <code>Document</code> object can potentially be a 
// heavyweight  object, depending on the underlying implementation. What is 
// really needed for this is a very lightweight object.  
// <code>DocumentFragment</code> is such an object.
// <p>Furthermore, various operations -- such as inserting nodes as children 
// of another <code>Node</code> -- may take <code>DocumentFragment</code> 
// objects as arguments;  this results in all the child nodes of the 
// <code>DocumentFragment</code>  being moved to the child list of this node.
// <p>The children of a <code>DocumentFragment</code> node are zero or more 
// nodes representing the tops of any sub-trees defining the structure of the 
// document. <code>DocumentFragment</code> nodes do not need to be 
// well-formed XML documents (although they do need to follow the rules 
// imposed upon well-formed XML parsed entities, which can have multiple top 
// nodes).  For example, a <code>DocumentFragment</code> might have only one 
// child and that child node could be a <code>Text</code> node. Such a 
// structure model  represents neither an HTML document nor a well-formed XML 
// document.  
// <p>When a <code>DocumentFragment</code> is inserted into a  
// <code>Document</code> (or indeed any other <code>Node</code> that may take 
// children) the children of the <code>DocumentFragment</code> and not the 
// <code>DocumentFragment</code>  itself are inserted into the 
// <code>Node</code>. This makes the <code>DocumentFragment</code> very 
// useful when the user wishes to create nodes that are siblings; the 
// <code>DocumentFragment</code> acts as the parent of these nodes so that the
// user can use the standard methods from the <code>Node</code>  interface, 
// such as <code>insertBefore()</code> and  <code>appendChild()</code>.  

namespace System.Xml {

    using System.Diagnostics;
    using System.Xml.XPath;

    // Represents a lightweight object that is useful for tree insert
    // operations.
    public class XmlDocumentFragment : XmlNode {
        XmlLinkedNode lastChild;

        protected internal XmlDocumentFragment( XmlDocument ownerDocument ): base( ) {
            if ( ownerDocument == null )
                throw new ArgumentException(Res.GetString(Res.Xdom_Node_Null_Doc));
            parentNode= ownerDocument;
        }

        // Gets the name of the node.
        public override String Name { 
            get { return OwnerDocument.strDocumentFragmentName;}
        }

        // Gets the name of the current node without the namespace prefix.
        public override String LocalName { 
            get { return OwnerDocument.strDocumentFragmentName;}
        }

        // Gets the type of the current node.
        public override XmlNodeType NodeType {
            get { return XmlNodeType.DocumentFragment;}
        }

        // Gets the parent of this node (for nodes that can have parents).
        public override XmlNode ParentNode {
            get { return null;}
        }

        // Gets the XmlDocument that contains this node.
        public override XmlDocument OwnerDocument {
            get { 
                return (XmlDocument)parentNode;
            }

        }

        // Gets or sets the markup representing just
        // the children of this node.
        public override string InnerXml {
            get {
                return base.InnerXml;
            }
            set {
                RemoveAll();
                XmlLoader loader = new XmlLoader();
                //Hack that the content is the same element
                loader.ParsePartialContent( this, value, XmlNodeType.Element );
            }
        }
        
        // Creates a duplicate of this node.
        public override XmlNode CloneNode(bool deep) {
            Debug.Assert( OwnerDocument != null );
            XmlDocument doc = OwnerDocument;
            XmlDocumentFragment clone = doc.CreateDocumentFragment();
            if (deep)
                clone.CopyChildren( doc, this, deep );
            return clone;                
        }

        internal override bool IsContainer {
            get { return true;}
        }

        internal override XmlLinkedNode LastNode {
            get { return lastChild;}
            set { lastChild = value;}
        }

        internal override bool IsValidChildType( XmlNodeType type ) {
            switch (type) {
                case XmlNodeType.Element:
                case XmlNodeType.Text:
                case XmlNodeType.EntityReference:
                case XmlNodeType.Comment:
                case XmlNodeType.Whitespace:
                case XmlNodeType.SignificantWhitespace:
                case XmlNodeType.ProcessingInstruction:
                case XmlNodeType.CDATA:
                    return true;

                case XmlNodeType.XmlDeclaration:
                    //if there is an XmlDeclaration node, it has to be the first node;
                    XmlNode firstNode = FirstChild;
                    if (firstNode == null || firstNode.NodeType != XmlNodeType.XmlDeclaration)
                        return true;
                    else
                        return false; //not allowed to insert a second XmlDeclaration node
                default:
                    return false;
            }
        }
        internal override bool CanInsertAfter( XmlNode newChild, XmlNode refChild ) {
            Debug.Assert(newChild != null); //should be checked that newChild is not null before this function call
            if (newChild.NodeType == XmlNodeType.XmlDeclaration) {
                if (refChild == null) {
                    //append at the end
                    return (LastNode == null);
                } else
                    return false;
            } 
            return true;
        }

        internal override bool CanInsertBefore( XmlNode newChild, XmlNode refChild ) {
            Debug.Assert(newChild != null); //should be checked that newChild is not null before this function call
            if (newChild.NodeType == XmlNodeType.XmlDeclaration) {
                return (refChild==null || refChild==FirstChild);
            }
            return true;
        }

        // Saves the node to the specified XmlWriter.
        public override void WriteTo(XmlWriter w) {
            WriteContentTo( w );
        }

        // Saves all the children of the node to the specified XmlWriter.
        public override void WriteContentTo(XmlWriter w) {
            foreach( XmlNode n in this ) {
                n.WriteTo( w );
            }
        }

        internal override XPathNodeType XPNodeType { get { return XPathNodeType.Root; } }
    }
}