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()); }
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); }
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; }