public void AcbValidationTest()
        {
            MCContext mcContext = new MCContext();
            ParagraphProperties pPr;
            Run run1, run2;
            Paragraph p = new Paragraph(pPr = new ParagraphProperties() { WordWrap = new WordWrap() { Val = true } },
                                         new OpenXmlMiscNode(System.Xml.XmlNodeType.Comment, "<!-- comments -->"),
                                         run1 = new Run(new Text("Text 1.")),
                                         run2 = new Run(new Text("Text 2.")));

            p.AddNamespaceDeclaration("w14test", "http://w14.com");

            OpenXmlUnknownElement ignorableElement = new OpenXmlUnknownElement("w14test", "span", "http://w14.com");
            ignorableElement.MCAttributes = new MarkupCompatibilityAttributes() { Ignorable = "w14test" };
            p.InsertAfter(ignorableElement, pPr);

            Run runInAcb = new Run(new Text("Text in ACB."));
            Run run2InAcb = new Run(new Text("Text 2 in ACB."));
            AlternateContent acb = new AlternateContent(new AlternateContentChoice() { Requires = "w14test" },
                                                        new AlternateContentFallback(runInAcb, run2InAcb));
            p.InsertAfter(acb, pPr);

            var validator = new OpenXmlValidator();
            var errors = validator.Validate(p);
            Assert.Equal(0, errors.Count());

            p.AppendChild(new OpenXmlUnknownElement("w15test", "art", "http://w15.com"));
            errors = validator.Validate(p);
            Assert.Equal(1, errors.Count());
            p.RemoveChild(p.LastChild);

            acb.LastChild.Append(new OpenXmlUnknownElement("w15test", "art", "http://w15.com"));
            errors = validator.Validate(p);
            Assert.Equal(1, errors.Count());

        }
Beispiel #2
0
        private protected override void Populate(XmlReader xmlReader, OpenXmlLoadMode loadMode)
        {
            // BUGBUG! following Read() move the cursor to next node, and skip the attributes of the first node
            // xmlReader.Read(); // read this element
            LoadAttributes(xmlReader);

            // TODO: handle non Text node ( PI, Comments, etc. )
            if (!xmlReader.IsEmptyElement)
            {
                Debug.Assert(xmlReader.IsStartElement());

                // load inner xml into LoadedInnerXml if there are any.
                ShadowElement = new OpenXmlUnknownElement(Prefix, LocalName, NamespaceUri)
                {
                    InnerXml = xmlReader.ReadInnerXml(),
                };
            }
            else
            {
                xmlReader.Skip();
            }

            // set raw outer xml to empty to indicate that it is parsed
            RawOuterXml = string.Empty;
        }
        /// <summary>
        /// Creates a new OpenXmlUnknownElement class by using the outer XML.
        /// </summary>
        /// <param name="outerXml">The outer XML of the element.</param>
        /// <returns>A new OpenXmlUnknownElement class.</returns>
        public static OpenXmlUnknownElement CreateOpenXmlUnknownElement(string outerXml)
        {
            if (String.IsNullOrEmpty(outerXml))
            {
                throw new ArgumentNullException("outerXml");
            }

            TextReader stringReader = new StringReader(outerXml);

            using (XmlReader xmlReader = XmlConvertingReaderFactory.Create(stringReader, OpenXmlElementContext.CreateDefaultXmlReaderSettings()))
            {
                do // O15:#3024890, Skip the leading whitespaces. OpenXmUnknownlElement ignores the Whitespace NodeType.
                {
                    // Fix bug #484153.
                    if (xmlReader.Read() && xmlReader.NodeType == XmlNodeType.Element)
                    {
                        OpenXmlUnknownElement newElement = new OpenXmlUnknownElement(xmlReader.Prefix, xmlReader.LocalName, xmlReader.NamespaceURI);
                        newElement.OuterXml = outerXml;
                        return(newElement);
                    }
                } while (xmlReader.NodeType == XmlNodeType.Whitespace);

                // This method always expects an Element NodeType is passed, and there may be one or more preceding Whitespace NodeTypes before the Element.
                // If it's not the case, then throw an exception.
                throw new ArgumentException(ExceptionMessages.InvalidOuterXml, "outerXml");
            }
        }
        /// <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)
        {
            OpenXmlUnknownElement element = new OpenXmlUnknownElement(this._prefix, this._tagName, this._namespaceUri);

            element._text = this.Text;
            element.CopyAttributes(this);
            if (deep)
            {
                element.CopyChilden(this, deep);
            }

            return(element);
        }
        /// <inheritdoc/>
        public override OpenXmlElement CloneNode(bool deep)
        {
            var element = new OpenXmlUnknownElement(_prefix, _tagName, _namespaceUri)
            {
                _text = Text,
            };

            element.CopyAttributes(this);

            if (deep)
            {
                element.CopyChilden(this, deep);
            }

            return(element);
        }
        internal static OpenXmlElement CreateElement(string namespaceUri, string name)
        {
            // Debug.Assert(namespaceUri != null);
            Debug.Assert(!string.IsNullOrEmpty(name));

            OpenXmlElement newElement = null;
            byte           nsId;

            if ((namespaceUri != null) && NamespaceIdMap.TryGetNamespaceId(namespaceUri, out nsId))
            {
                newElement = CreateElement(nsId, name);
            }

            if (newElement == null)
            {
                // return unknown element instead of throw exception.
                newElement = new OpenXmlUnknownElement();
            }

            return(newElement);
        }
        internal static OpenXmlElement CreateElement(string namespaceUri, string name)
        {
            // Debug.Assert(namespaceUri != null);
            Debug.Assert(!String.IsNullOrEmpty(name));

            //
            OpenXmlElement newElement = null;
            byte nsId;

            if ((namespaceUri != null) && NamespaceIdMap.TryGetNamespaceId(namespaceUri, out nsId))
            {
                newElement = CreateElement(nsId, name);
            }

            if (newElement == null)
            {
                // return unknown element instead of throw exception.
                newElement = new OpenXmlUnknownElement();
            }

            return newElement;
        }
        /// <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)
        {
            OpenXmlUnknownElement element = new OpenXmlUnknownElement(this._prefix, this._tagName, this._namespaceUri);
            element._text = this.Text;
            element.CopyAttributes(this);
            if(deep)
            {
                element.CopyChilden(this, deep);
            }

            return element;
        }
        /// <summary>
        /// Creates a new OpenXmlUnknownElement class by using the outer XML.
        /// </summary>
        /// <param name="outerXml">The outer XML of the element.</param>
        /// <returns>A new OpenXmlUnknownElement class.</returns>
        public static OpenXmlUnknownElement CreateOpenXmlUnknownElement(string outerXml)
        {
            if (String.IsNullOrEmpty(outerXml))
            {
                throw new ArgumentNullException("outerXml");
            }

            TextReader stringReader = new StringReader(outerXml);
            using (XmlReader xmlReader = XmlConvertingReaderFactory.Create(stringReader, OpenXmlElementContext.CreateDefaultXmlReaderSettings()))
            {
                do // O15:#3024890, Skip the leading whitespaces. OpenXmUnknownlElement ignores the Whitespace NodeType.
                {
                    // Fix bug #484153.
                    if (xmlReader.Read() && xmlReader.NodeType == XmlNodeType.Element)
                    {
                        OpenXmlUnknownElement newElement = new OpenXmlUnknownElement(xmlReader.Prefix, xmlReader.LocalName, xmlReader.NamespaceURI);
                        newElement.OuterXml = outerXml;
                        return newElement;
                    }

                } while (xmlReader.NodeType == XmlNodeType.Whitespace);

                // This method always expects an Element NodeType is passed, and there may be one or more preceding Whitespace NodeTypes before the Element.
                // If it's not the case, then throw an exception.
                throw new ArgumentException(ExceptionMessages.InvalidOuterXml, "outerXml");
            }

        }
        public void GetChildMcTest()
        {
            MCContext mcContext = new MCContext();
            ParagraphProperties pPr;
            Run run1, run2;
            Paragraph p = new Paragraph(pPr = new ParagraphProperties() { WordWrap = new WordWrap() { Val = true } },
                                         new OpenXmlMiscNode(System.Xml.XmlNodeType.Comment, "<!-- comments -->"),
                                         run1 = new Run(new Text("Text 1.")),
                                         run2 = new Run(new Text("Text 2.")));

            var target = p.GetFirstChildMc(mcContext, FileFormatVersions.Office2007);
            Assert.Same(pPr, target);
            target = p.GetNextChildMc(target, mcContext, FileFormatVersions.Office2007);
            Assert.Same(run1, target);
            target = p.GetNextChildMc(target, mcContext, FileFormatVersions.Office2007);
            Assert.Same(run2, target);

            OpenXmlUnknownElement ignorableElement = new OpenXmlUnknownElement("w14test", "span", "http://w14.com");
            p.AddNamespaceDeclaration("w14test", "http://w14.com");

            ignorableElement.MCAttributes = new MarkupCompatibilityAttributes() { Ignorable="w14test" };
            p.InsertAfter(ignorableElement, pPr);
            
            mcContext = new MCContext();
            target = p.GetFirstChildMc(mcContext, FileFormatVersions.Office2007);
            Assert.Same(pPr, target);
            target = p.GetNextChildMc(target, mcContext, FileFormatVersions.Office2007);
            Assert.Same(run1, target);
            target = p.GetNextChildMc(target, mcContext, FileFormatVersions.Office2007);
            Assert.Same(run2, target);

            Run runInAcb = new Run(new Text("Text in ACB."));
            AlternateContent acb = new AlternateContent(new AlternateContentChoice() { Requires = "w14test" },
                                                        new AlternateContentFallback(runInAcb));
            p.InsertAfter(acb, pPr);

            mcContext = new MCContext();
            target = p.GetFirstChildMc(mcContext, FileFormatVersions.Office2007);
            Assert.Same(pPr, target);
            target = p.GetNextChildMc(target, mcContext, FileFormatVersions.Office2007);
            Assert.Same(runInAcb, target);
            target = p.GetNextChildMc(target, mcContext, FileFormatVersions.Office2007);
            Assert.Same(run1, target);
            target = p.GetNextChildMc(target, mcContext, FileFormatVersions.Office2007);
            Assert.Same(run2, target);



        }
Beispiel #11
0
        private protected 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

                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(LocalName));
                }
                else
                {
                    while (!xmlReader.EOF)
                    {
                        if (xmlReader.NodeType == XmlNodeType.EndElement)
                        {
                            Debug.Assert(xmlReader.LocalName.Equals(LocalName));
                            break;
                        }
                        else if (string.IsNullOrEmpty(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
                            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 = ElementFactory(xmlReader);
                            child.Load(xmlReader, OpenXmlLoadMode.Full);
                            unwanted++;

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

                            ShadowElement.AppendChild(child);
                        }
                    }
                }

                if (unwanted == 0)
                {
                    // only text node, no unwanted children
                    Debug.Assert(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(RawInnerText);
                        break;

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

                    case XmlNodeType.SignificantWhitespace:
                    case XmlNodeType.Whitespace:     /* O15:#3024890 */
                        textNode = OpenXmlMiscNode.CreateFromSignificantWhitespace(RawInnerText);
                        break;
                    }

                    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
            RawOuterXml = string.Empty;
        }