コード例 #1
0
        private bool ReadRoot()
        {
            Debug.Assert(_elementState == ElementState.Null);
            Debug.Assert(_elementStack.Count == 0);

            // TODO: should we take care of entity? <!DOCTYPE page [ <!ENTITY company "Microsoft"> ]>
            // TODO: is it OK that we skip all prolog ( DOCTYPE, Comment, PT ) ?

            _xmlReader.MoveToContent();

            while (!_xmlReader.EOF && _xmlReader.NodeType != XmlNodeType.Element)
            {
                _xmlReader.Skip();
            }

            if (_xmlReader.EOF || !_xmlReader.IsStartElement())
            {
                throw new InvalidDataException(ExceptionMessages.PartIsEmpty);
            }

            // create the root element object
            OpenXmlElement rootElement = RootElementFactory.CreateElement(_xmlReader.NamespaceURI, _xmlReader.LocalName);

            if (rootElement == null)
            {
                throw new InvalidDataException(ExceptionMessages.PartUnknown);
            }

            _elementStack.Push(rootElement);

            LoadAttributes();

            if (_xmlReader.IsEmptyElement)
            {
                _elementState = ElementState.LeafStart;
                rootElement.Load(_xmlReader, OpenXmlLoadMode.Full);
            }
            else
            {
                _elementState = ElementState.Start;
            }
            return(true);
        }
コード例 #2
0
        /// <summary>
        /// Populates the XML into a strong typed DOM tree.
        /// </summary>
        /// <param name="xmlReader">The XmlReader to read the XML content.</param>
        /// <param name="loadMode">Specifies a load mode that is either lazy or full.</param>
        private protected override void Populate(XmlReader xmlReader, OpenXmlLoadMode loadMode)
        {
            LoadAttributes(xmlReader);

            if (!xmlReader.IsEmptyElement)
            {
                xmlReader.Read(); // read this element

                while (!xmlReader.EOF)
                {
                    // O15:#3024890, OpenXmlCompositElement ignores the Whitespace NodeType.
                    if (xmlReader.NodeType == XmlNodeType.Whitespace)
                    {
                        xmlReader.Skip();
                        continue;
                    }
                    else if (xmlReader.NodeType == XmlNodeType.EndElement)
                    {
                        Debug.Assert(xmlReader.LocalName.Equals(LocalName));
                        xmlReader.Skip(); // move to next node
                        break;
                    }

                    OpenXmlElement element = ElementFactory(xmlReader);

                    // set parent before Load( ) call. AlternateContentChoice need parent info on loading.
                    element.Parent = this;

                    bool isACB = element is AlternateContent;
                    if (isACB && element.OpenXmlElementContext != null)
                    {
                        element.OpenXmlElementContext.ACBlockLevel++;
                    }

                    bool mcContextPushed = false;
                    if (!(element is OpenXmlMiscNode))
                    {
                        // push MC context based on the context of the child element to be loaded
                        mcContextPushed = PushMcContext(xmlReader);
                    }

                    //Process the element according to the MC behavior
                    var action = ElementAction.Normal;
                    if (OpenXmlElementContext != null && OpenXmlElementContext.MCSettings.ProcessMode != DocumentFormat.OpenXml.Packaging.MarkupCompatibilityProcessMode.NoProcess)
                    {
                        action = OpenXmlElementContext.MCContext.GetElementAction(element, OpenXmlElementContext.MCSettings.TargetFileFormatVersions);
                    }

                    element.Load(xmlReader, loadMode);

                    if (mcContextPushed)
                    {
                        PopMcContext();
                    }

                    if (isACB && element.OpenXmlElementContext != null)
                    {
                        element.OpenXmlElementContext.ACBlockLevel--;
                    }

                    switch (action)
                    {
                    case ElementAction.Normal:
                    {
                        AddANode(element);
                        break;
                    }

                    case ElementAction.Ignore:
                    {
                        element.Parent = null;
                        continue;
                    }

                    case ElementAction.ProcessContent:
                    {
                        element.Parent = null;
                        while (element.ChildElements.Count > 0)
                        {
                            var node = element.FirstChild;
                            node.Remove();
                            OpenXmlElement newnode = null;

                            // If node is an UnknowElement, we should try to see whether the parent element can load the node as strong typed element
                            if (node is OpenXmlUnknownElement)
                            {
                                newnode = ElementFactory(node.Prefix, node.LocalName, node.NamespaceUri);
                                if (!(newnode is OpenXmlUnknownElement))
                                {
                                    // The following method will load teh element in MCMode.Full
                                    // since the node is already MC-processed when loading as unknown type, full loading the outerXml is fine
                                    newnode.OuterXml = node.OuterXml;

                                    // unnecessary xmlns attribute will be added, remove it.
                                    RemoveUnnecessaryExtAttr(node, newnode);
                                }
                                else
                                {
                                    newnode = null;
                                }
                            }

                            if (newnode != null)
                            {
                                AddANode(newnode);
                            }
                            else
                            {
                                //append the orignal node
                                AddANode(node);
                            }
                        }

                        break;
                    }

                    case ElementAction.ACBlock:
                    {
                        var effectiveNode = OpenXmlElementContext.MCContext.GetContentFromACBlock(element as AlternateContent, OpenXmlElementContext.MCSettings.TargetFileFormatVersions);
                        if (effectiveNode == null)
                        {
                            break;
                        }

                        element.Parent       = null;
                        effectiveNode.Parent = null;
                        while (effectiveNode.FirstChild != null)
                        {
                            var node = effectiveNode.FirstChild;
                            node.Remove();
                            AddANode(node);
                            node.CheckMustUnderstandAttr();
                        }

                        break;
                    }
                    }
                }
            }
            else
            {
                xmlReader.Skip();
            }

            // Set raw outer xml to empty to indicate that it passed
            RawOuterXml = string.Empty;
        }
コード例 #3
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;
        }