예제 #1
0
        /// <summary>
        /// When overridden in a derived class, creates a duplicate of the node.
        /// </summary>
        /// <param name="deep">
        /// Specify true to recursively clone the subtree under the specified
        /// node; false to clone only the node itself.
        /// </param>
        /// <returns>The cloned node. </returns>
        public override OpenXmlElement CloneNode(bool deep)
        {
            OpenXmlMiscNode element = new OpenXmlMiscNode(this.XmlNodeType);

            element.OuterXml = this.OuterXml;

            return(element);
        }
예제 #2
0
        internal static OpenXmlMiscNode CreateFromSignificantWhitespace(string whitespace)
        {
            Debug.Assert(whitespace != null);

            var newMiscNode = new OpenXmlMiscNode(XmlNodeType.SignificantWhitespace);

            newMiscNode.Value       = whitespace;
            newMiscNode.RawOuterXml = whitespace;
            return(newMiscNode);
        }
예제 #3
0
        internal static OpenXmlMiscNode CreateFromCdata(string value)
        {
            Debug.Assert(value != null);

            var newMiscNode = new OpenXmlMiscNode(XmlNodeType.CDATA);

            newMiscNode.Value       = value;
            newMiscNode.RawOuterXml = string.Format(CultureInfo.InvariantCulture, "<![CDATA[{0}]]>", value);
            return(newMiscNode);
        }
예제 #4
0
        internal static OpenXmlMiscNode CreateFromText(string text)
        {
            Debug.Assert(text != null);

            var newMiscNode = new OpenXmlMiscNode(XmlNodeType.Text);

            newMiscNode.Value       = text;
            newMiscNode.RawOuterXml = text;
            return(newMiscNode);
        }
        internal override void Populate(XmlReader xmlReader, OpenXmlLoadMode loadMode)
        {
            if (String.IsNullOrEmpty(this._tagName))
            {
                this._tagName      = xmlReader.LocalName;
                this._prefix       = xmlReader.Prefix;
                this._namespaceUri = xmlReader.NamespaceURI;
            }
            else
            {
                Debug.Assert(String.Equals(this._tagName, xmlReader.LocalName));
                Debug.Assert(String.Equals(this._prefix, xmlReader.Prefix));
                Debug.Assert(String.Equals(this._namespaceUri, xmlReader.NamespaceURI));
            }

            // load children elements
            base.Populate(xmlReader, loadMode);

            if (this.FirstChild != null && this.FirstChild.NextSibling() == null)
            {
                // only one child
                OpenXmlMiscNode miscNode = this.FirstChild as OpenXmlMiscNode;
                if (miscNode != null)
                {
                    switch (miscNode.XmlNodeType)
                    {
                    case XmlNodeType.Text:
                    case XmlNodeType.CDATA:
                    case XmlNodeType.SignificantWhitespace:
                        this._text = miscNode.OuterXml;     // is this OK?
                        this.RemoveChild(miscNode);
                        break;

                    case XmlNodeType.Whitespace:     // O15:#3024890, OpenXmlUnknownElement ignores the Whitespace NodeType.
                    default:
                        break;
                    }
                }
            }
        }
예제 #6
0
        //internal override void Load(XmlReader xmlReader)
        //{
        //    LoadAttributes(xmlReader);
        //    this.Text = xmlReader.ReadElementString();
        //}
        internal override void Populate(XmlReader xmlReader, OpenXmlLoadMode loadMode)
        {
            LoadAttributes(xmlReader);

            if (!xmlReader.IsEmptyElement)
            {                     // only when element is not empty (not  <element />).
                xmlReader.Read(); // read this element

                this.RawInnerText = string.Empty;

                int         unwanted         = 0;
                int         textNodePosition = -1; // the position of the text in the ShadowElement's children when there are other unexpected node.
                XmlNodeType textNodeType     = XmlNodeType.Text;

                if (xmlReader.NodeType == XmlNodeType.EndElement)
                {
                    Debug.Assert(xmlReader.LocalName.Equals(this.LocalName));
                }
                else
                {
                    while (!xmlReader.EOF)
                    {
                        if (xmlReader.NodeType == XmlNodeType.EndElement)
                        {
                            Debug.Assert(xmlReader.LocalName.Equals(this.LocalName));
                            break;
                        }
                        else if (string.IsNullOrEmpty(this.RawInnerText) &&
                                 (xmlReader.NodeType == XmlNodeType.Text ||
                                  xmlReader.NodeType == XmlNodeType.CDATA ||
                                  xmlReader.NodeType == XmlNodeType.SignificantWhitespace ||
                                  xmlReader.NodeType == XmlNodeType.Whitespace /* O15:#3024890 */))
                        {
                            // text or CDATA
                            // scenario: normal text element <Application>Microsoft Office Word</Application>
                            // scenario: <w:t>This is <![CDATA[Xml Example <tag>text</tag>.]]> 1</w:t>

                            // only load text when no text is loaded,
                            // for case "<foo/>Text1<bar/>Text2", only load "Text1", very rare case

                            this.RawInnerText = xmlReader.Value;
                            textNodePosition  = unwanted;
                            textNodeType      = xmlReader.NodeType;

                            xmlReader.Read();
                        }
                        else
                        {
                            Debug.Assert(xmlReader.NodeType != XmlNodeType.EntityReference);

                            // Load unexpected children if there are any.

                            OpenXmlElement child = this.ElementFactory(xmlReader);
                            child.Load(xmlReader, OpenXmlLoadMode.Full);
                            unwanted++;

                            if (this.ShadowElement == null)
                            {
                                this.ShadowElement = new OpenXmlUnknownElement(this.Prefix, this.LocalName, this.NamespaceUri);
                            }

                            this.ShadowElement.AppendChild(child);
                        }
                    }
                }

                if (unwanted == 0)
                {
                    // only text node, no unwanted children
                    Debug.Assert(this.ShadowElement == null);
                }
                else if (textNodePosition > -1)
                {
                    // place an OpenXmlMiscNode for the loaded text in the ShadowElement so that we can write out correct content in serialization.
                    OpenXmlMiscNode textNode = null;
                    switch (textNodeType)
                    {
                    case XmlNodeType.Text:
                        textNode = OpenXmlMiscNode.CreateFromText(this.RawInnerText);
                        break;

                    case XmlNodeType.CDATA:
                        textNode = OpenXmlMiscNode.CreateFromCdata(this.RawInnerText);
                        break;

                    case XmlNodeType.SignificantWhitespace:
                    case XmlNodeType.Whitespace:     /* O15:#3024890 */
                        textNode = OpenXmlMiscNode.CreateFromSignificantWhitespace(this.RawInnerText);
                        break;
                    }
                    this.ShadowElement.InsertAt(textNode, textNodePosition);
                }
                else
                {
                    // textNodePosition == -1, no text loaded.
                }
            }

            xmlReader.Skip(); // skip the end tag

            // set raw outer xml to empty to indicate that it is passed
            this.RawOuterXml = string.Empty;
        }
예제 #7
0
        internal static OpenXmlMiscNode CreateFromSignificantWhitespace(string whitespace)
        {
            Debug.Assert(whitespace != null);

            var newMiscNode = new OpenXmlMiscNode(XmlNodeType.SignificantWhitespace);
            newMiscNode.Value = whitespace;
            newMiscNode.RawOuterXml = whitespace;
            return newMiscNode;
        }
예제 #8
0
        internal static OpenXmlMiscNode CreateFromCdata(string value)
        {
            Debug.Assert(value != null);

            var newMiscNode = new OpenXmlMiscNode(XmlNodeType.CDATA);
            newMiscNode.Value = value;
            newMiscNode.RawOuterXml = String.Format(CultureInfo.InvariantCulture, "<![CDATA[{0}]]>", value); ;
            return newMiscNode;
        }
예제 #9
0
        internal static OpenXmlMiscNode CreateFromText(string text)
        {
            Debug.Assert(text != null);

            var newMiscNode = new OpenXmlMiscNode(XmlNodeType.Text);
            newMiscNode.Value = text;
            newMiscNode.RawOuterXml = text;
            return newMiscNode;
        }
예제 #10
0
        /// <summary>
        /// When overridden in a derived class, creates a duplicate of the node. 
        /// </summary>
        /// <param name="deep">
        /// Specify true to recursively clone the subtree under the specified
        /// node; false to clone only the node itself.
        /// </param>
        /// <returns>The cloned node. </returns>
        public override OpenXmlElement CloneNode(bool deep)
        {
            OpenXmlMiscNode element = new OpenXmlMiscNode(this.XmlNodeType);

            element.OuterXml = this.OuterXml;

            return element;
        }
예제 #11
0
        public void ElementCloneTest()
        {
            using(MemoryStream stream = new MemoryStream(TestFileStreams.mcdoc))
            using (var doc = WordprocessingDocument.Open(stream, false))
            {
                // Shallow clone the body, which doesn't have attributes
                var body = doc.MainDocumentPart.Document.Body;
                var clonedBody = body.CloneNode(false);
                Assert.False(clonedBody.HasChildren);
                Assert.Equal(body.HasAttributes, clonedBody.HasAttributes); //Cloned Body has no attributes.
                Assert.Equal(body.ExtendedAttributes.Count(), clonedBody.ExtendedAttributes.Count());

                // Shallow clone the first paragraph, which has attributes
                var paragraph = body.Descendants<Paragraph>().First();
                var clonedParagraph = paragraph.CloneNode(false);
                Assert.False(clonedParagraph.HasChildren);
                Assert.True(clonedParagraph.HasAttributes);
                Assert.Equal(paragraph.Attributes.Count(), clonedParagraph.Attributes.Count());
                Assert.Equal(paragraph.ExtendedAttributes.Count(), clonedParagraph.ExtendedAttributes.Count());

                // Deep clone the document
                var clonedDocument = doc.MainDocumentPart.Document.CloneNode(true);
                Assert.True(clonedDocument.HasChildren);
                Assert.Equal(doc.MainDocumentPart.Document.ChildElements.Count, clonedDocument.ChildElements.Count);
                Assert.Equal(doc.MainDocumentPart.Document.Descendants().Count(), clonedDocument.Descendants().Count());
                var docEnumerator = doc.MainDocumentPart.Document.Descendants().GetEnumerator();
                foreach (var elem in clonedDocument.Descendants())
                {
                    Assert.True(docEnumerator.MoveNext());
                    var curElem = docEnumerator.Current;
                    Assert.Equal(curElem.GetType(), elem.GetType());
                    Assert.Equal(curElem.NamespaceUri, elem.NamespaceUri);
                    Assert.Equal(curElem.XmlQualifiedName, elem.XmlQualifiedName);
                    Assert.Equal(curElem.Attributes == null, elem.Attributes == null);
                    if (curElem.Attributes != null)
                    {
                        Assert.Equal(curElem.Attributes.Length, elem.Attributes.Length);
                    }
                    Assert.Equal(curElem.ExtendedAttributes.Count(), elem.ExtendedAttributes.Count());
                    var a1 = curElem.ExtendedAttributes.ToArray();
                    var a2 = elem.ExtendedAttributes.ToArray();
                    for(int i = 0; i< a1.Length; i++)
                    {
                        Assert.Equal(a1[i].NamespaceUri, a2[i].NamespaceUri);
                        Assert.Equal(a1[i].LocalName, a2[i].LocalName);
                        Assert.Equal(a1[i].Value, a2[i].Value);
                    }

                    Assert.Equal(curElem.MCAttributes == null, elem.MCAttributes == null);
                    if (curElem is OpenXmlLeafTextElement)
                    {
                        Assert.Equal(((OpenXmlLeafTextElement)curElem).Text, ((OpenXmlLeafTextElement)elem).Text);
                    }
                }
                // Deep clone the unknown element
                var unknown = doc.MainDocumentPart.Document.Descendants<OpenXmlUnknownElement>().Where(e => e.LocalName == "wsp").First();
                var clonedUnknown = unknown.CloneNode(true);
                Assert.Equal(unknown.OuterXml, clonedUnknown.OuterXml);

                // Clone the OpenXmlMiscNode
                var miscNode = new OpenXmlMiscNode(System.Xml.XmlNodeType.Comment, "<!-- my comment -->");
                var clonedMiscNode = miscNode.CloneNode(true) as OpenXmlMiscNode;
                Assert.NotNull(clonedMiscNode);
                Assert.Equal(miscNode.XmlNodeType, clonedMiscNode.XmlNodeType);
                Assert.Equal(miscNode.OuterXml, clonedMiscNode.OuterXml);
                
                // Shallow clone mc element
                var acb = body.Descendants<AlternateContent>().First();
                acb.MCAttributes = new MarkupCompatibilityAttributes();
                acb.MCAttributes.Ignorable = "w14";
                acb.MCAttributes.MustUnderstand = "wp";
                acb.MCAttributes.PreserveAttributes = "a";
                acb.MCAttributes.PreserveElements = "w14";
                acb.MCAttributes.ProcessContent = "wp";
                var clonedAcb = acb.CloneNode(false);
                Assert.NotNull(clonedAcb.MCAttributes);
                Assert.Equal(acb.MCAttributes.Ignorable.Value, clonedAcb.MCAttributes.Ignorable.Value);
                Assert.Equal(acb.MCAttributes.MustUnderstand.Value, clonedAcb.MCAttributes.MustUnderstand.Value);
                Assert.Equal(acb.MCAttributes.PreserveAttributes.Value, clonedAcb.MCAttributes.PreserveAttributes.Value);
                Assert.Equal(acb.MCAttributes.PreserveElements.Value, clonedAcb.MCAttributes.PreserveElements.Value);
                Assert.Equal(acb.MCAttributes.ProcessContent.Value, clonedAcb.MCAttributes.ProcessContent.Value);
            }
        }