public void LeafElementValidateTest()
        {
            string runOuterXml = "<w:r xmlns:w=\"http://schemas.openxmlformats.org/wordprocessingml/2006/main\">" +
            "<w:rPr><w:strike /><w:vanish><!-- comments is ok --></w:vanish><w:webHidden><w:invalidChild /></w:webHidden></w:rPr>" +
            "<w:t>Run Text.</w:t><w:t><!-- comments is ok -->Text 2</w:t><w:t>Text 3.<invalidElement /></w:t></w:r>";

            SchemaValidator target = new SchemaValidator();
            var openxmlElement = new Run(runOuterXml);
            ValidationResult result = target.Validate(openxmlElement);
            Assert.False(result.Valid);
            Assert.Equal(2, result.Errors.Count);

            Assert.Same(openxmlElement.GetFirstChild<RunProperties>().WebHidden, result.Errors[0].Node);
            Assert.Equal("Sch_InvalidChildinLeafElement", result.Errors[0].Id);
            Assert.Equal("The element 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:webHidden' is a leaf element and cannot contain children.", result.Errors[0].Description);

            Assert.Same(openxmlElement.LastChild, result.Errors[1].Node);
            Assert.Equal("Sch_InvalidChildinLeafElement", result.Errors[1].Id);
            Assert.Equal("The element 'http://schemas.openxmlformats.org/wordprocessingml/2006/main:t' is a leaf element and cannot contain children.", result.Errors[1].Description);
        }
        public void AcbSyntaxValidationTest()
        {
            var validator = new SchemaValidator();
            var element = new Run();
            var acFallback = new AlternateContentFallback();
            var ac = element.AppendChild(new AlternateContent());
            var errors = validator.Validate(ac).Errors;
            // Error case: must have one choice, can not have AlternateContent as di
            Assert.Equal(1, errors.Count());
            Assert.Equal("Sch_IncompleteContentExpectingComplex", errors[0].Id);

            ac.AddNamespaceDeclaration("o15", "http://o15.com");
            //ac.NamespaceDeclarations
            ac.AppendChild(new AlternateContentChoice() { Requires = "o15" });
            errors = validator.Validate(ac).Errors;
            Assert.Equal(0, errors.Count());

            ac.AddNamespaceDeclaration("o14", "http://o14.com");
            ac.PrependChild(new AlternateContentChoice() { Requires = "o14" });
            errors = validator.Validate(ac).Errors;
            Assert.Equal(0, errors.Count());

            ac.AppendChild(acFallback);
            errors = validator.Validate(ac).Errors;
            Assert.Equal(0, errors.Count());

            // Error case: should not contains AlternateContent directly as child.
            ac.AppendChild(new AlternateContent());
            errors = validator.Validate(ac).Errors;
            Assert.Equal(1, errors.Count());
            Assert.Equal(ValidationErrorType.MarkupCompatibility, errors.First().ErrorType);
            Assert.Equal("Sch_InvalidElementContentExpectingComplex", errors.First().Id);
            ac.RemoveChild(ac.LastChild);

            // Error case: can only contains one Fallback.
            ac.AppendChild(new AlternateContentFallback());
            errors = validator.Validate(ac).Errors;
            Assert.Equal(1, errors.Count());
            Assert.Equal(ValidationErrorType.MarkupCompatibility, errors.First().ErrorType);
            Assert.Equal("Sch_InvalidElementContentExpectingComplex", errors.First().Id);
            ac.RemoveChild(ac.LastChild);

            ac.RemoveChild(acFallback);
            // Error case: wrong sequence
            ac.PrependChild(acFallback);
            errors = validator.Validate(ac).Errors;
            Assert.Equal(1, errors.Count());
            Assert.Equal(ValidationErrorType.MarkupCompatibility, errors.First().ErrorType);
            Assert.Equal("Sch_IncompleteContentExpectingComplex", errors.First().Id);
            ac.RemoveChild(acFallback);
            ac.Append(acFallback);

            var langAttribute = new OpenXmlAttribute("xml:lang", "http://www.w3.org/XML/1998/namespace", "en-us");
            ac.SetAttribute(langAttribute);
            errors = validator.Validate(ac).Errors;
            Assert.Equal(1, errors.Count());
            Assert.Equal(ValidationErrorType.MarkupCompatibility, errors.First().ErrorType);
            Assert.Equal("MC_InvalidXmlAttribute", errors.First().Id);
            Assert.Equal( "The AlternateContent element should not have an xml:lang or xml:space attribute.", errors[0].Description);
            ac.RemoveAttribute(langAttribute.LocalName, langAttribute.NamespaceUri);

            ac.FirstChild.SetAttribute(langAttribute);
            errors = validator.Validate(ac).Errors;
            Assert.Equal(1, errors.Count());
            Assert.Same(ac.FirstChild, errors[0].Node);
            Assert.Equal(ValidationErrorType.MarkupCompatibility, errors.First().ErrorType);
            Assert.Equal("MC_InvalidXmlAttribute", errors.First().Id);
            Assert.Equal("The Choice element should not have an xml:lang or xml:space attribute.", errors[0].Description);
            ac.FirstChild.RemoveAttribute(langAttribute.LocalName, langAttribute.NamespaceUri);

            ac.LastChild.SetAttribute(langAttribute);
            errors = validator.Validate(ac).Errors;
            Assert.Equal(1, errors.Count());
            Assert.Same(ac.LastChild, errors[0].Node);
            Assert.Equal(ValidationErrorType.MarkupCompatibility, errors.First().ErrorType);
            Assert.Equal("MC_InvalidXmlAttribute", errors.First().Id);
            Assert.Equal("The Fallback element should not have an xml:lang or xml:space attribute.", errors[0].Description);
            ac.LastChild.RemoveAttribute(langAttribute.LocalName, langAttribute.NamespaceUri);

            AlternateContentChoice choice1 = ac.FirstChild as AlternateContentChoice;
            choice1.Requires = "o17 o15";
            errors = validator.Validate(ac).Errors;
            Assert.Equal(1, errors.Count());
            Assert.Equal(ValidationErrorType.MarkupCompatibility, errors.First().ErrorType);
            Assert.Same(choice1, errors[0].Node);
            Assert.Equal("MC_InvalidRequiresAttribute", errors.First().Id);
            Assert.Equal("The Requires attribute is invalid - The value 'o17 o15' contains an invalid prefix that is not defined.", errors[0].Description);

            choice1.Requires = null;
            errors = validator.Validate(ac).Errors;
            Assert.Equal(ValidationErrorType.MarkupCompatibility, errors.First().ErrorType);
            Assert.Equal(1, errors.Count());
            Assert.Same(choice1, errors[0].Node);
            Assert.Equal("MC_MissedRequiresAttribute", errors.First().Id);
            Assert.Equal("All Choice elements must have a Requires attribute whose value contains a whitespace delimited list of namespace prefixes.", errors[0].Description);
        }
        public void CompatibilityRuleAttributesValidationTest()
        {
            var validator = new SchemaValidator();
            var element = new Paragraph();
            var run = new Run();
            
            element.AppendChild(run);

            var result = validator.Validate(element);
            Assert.True(result.Valid);

            element.AddNamespaceDeclaration("o15", "http://o15.com");
            result = validator.Validate(element);
            Assert.True(result.Valid);

            run.MCAttributes = new MarkupCompatibilityAttributes();
            run.MCAttributes.Ignorable = "o15";
            result = validator.Validate(element);
            Assert.True(result.Valid);

            run.AddNamespaceDeclaration("w15", "http://w15.com");
            result = validator.Validate(element);
            Assert.True(result.Valid);

            run.MCAttributes.Ignorable = "o15 w15";
            result = validator.Validate(element);
            Assert.True(result.Valid);

            run.MCAttributes.PreserveAttributes = "  o15:id w15:*";
            run.MCAttributes.PreserveElements = "o15:*  w15:*  ";
            run.MCAttributes.ProcessContent = "  o15:newE   w15:newW  ";
            result = validator.Validate(element);
            Assert.True(result.Valid);

            run.MCAttributes.PreserveElements = "x15:* ";
            result = validator.Validate(element);
            Assert.False(result.Valid);
            Assert.Equal(1, result.Errors.Count);
            Assert.Equal(ValidationErrorType.MarkupCompatibility, result.Errors[0].ErrorType);
            Assert.Equal("MC_InvalidPreserveElementsAttribute", result.Errors[0].Id);

            run.MCAttributes.Ignorable = null;
            run.MCAttributes.PreserveAttributes = null;
            run.MCAttributes.PreserveElements = "w15:*";
            run.MCAttributes.ProcessContent = "";
            result = validator.Validate(element);
            Assert.False(result.Valid);
            Assert.Equal(1, result.Errors.Count);
            Assert.Equal(ValidationErrorType.MarkupCompatibility, result.Errors[0].ErrorType);
            Assert.Equal("MC_InvalidPreserveElementsAttribute", result.Errors[0].Id);

            run.MCAttributes.Ignorable = "o15";
            run.MCAttributes.PreserveAttributes = "";
            run.MCAttributes.PreserveElements = "w15:*";
            result = validator.Validate(element);
            Assert.False(result.Valid);
            Assert.Equal(1, result.Errors.Count);
            Assert.Equal(ValidationErrorType.MarkupCompatibility, result.Errors[0].ErrorType);
            Assert.Equal("MC_InvalidPreserveElementsAttribute", result.Errors[0].Id);
            run.MCAttributes.PreserveElements = null;

            run.MCAttributes.ProcessContent = "w14:newW";
            result = validator.Validate(element);
            Assert.False(result.Valid);
            Assert.Equal(1, result.Errors.Count);
            Assert.Equal(ValidationErrorType.MarkupCompatibility, result.Errors[0].ErrorType);
            Assert.Equal("MC_InvalidProcessContentAttribute", result.Errors[0].Id);
            run.MCAttributes.ProcessContent = null;

            var spaceAttribute = new OpenXmlAttribute("xml:space", "http://www.w3.org/XML/1998/namespace", "preserve");
            run.MCAttributes.ProcessContent = "o15:newP";
            run.SetAttribute(spaceAttribute);
            result = validator.Validate(element);
            Assert.False(result.Valid);
            Assert.Equal(1, result.Errors.Count);
            Assert.Equal(ValidationErrorType.MarkupCompatibility, result.Errors[0].ErrorType);
            Assert.Equal("MC_InvalidXmlAttributeWithProcessContent", result.Errors[0].Id);
            run.MCAttributes.ProcessContent = null;
            
            run.SetAttribute(new OpenXmlAttribute("o15:id", "http://o15.com", "1"));
            result = validator.Validate(element);
            Assert.True(result.Valid);

            run.MCAttributes.Ignorable = "o15 w15 x15";
            result = validator.Validate(element);
            Assert.False(result.Valid);
            Assert.Equal(1, result.Errors.Count);
            Assert.Equal(ValidationErrorType.MarkupCompatibility, result.Errors[0].ErrorType);
            Assert.Equal("MC_InvalidIgnorableAttribute", result.Errors[0].Id);

            run.MCAttributes.Ignorable = "o15 w15";
            run.SetAttribute(new OpenXmlAttribute("x15:id", "http://x15.com", "1"));
            result = validator.Validate(element);
            Assert.False(result.Valid);
            Assert.Equal(1, result.Errors.Count);
        }