Ejemplo n.º 1
0
        public void PartialDocument_PartialSerializedDocumentCreated()
        {
            Phase lMockPhase1 = new Phase();

            lMockPhase1.ID = "error";

            SchematronDocument lDocument = new SchematronDocument();

            lDocument.Phases.Add(lMockPhase1);

            SchematronDocumentSerializer lBuilder = new SchematronDocumentSerializer();
            string lSerializedModel = lBuilder.SerializeDocument(lDocument);

            Assert.IsFalse(string.IsNullOrEmpty(lSerializedModel), "A valid partial document was not created");

            XmlDocument lSerializedDocument = new XmlDocument();

            lSerializedDocument.LoadXml(lSerializedModel);

            XmlNamespaceManager lManager = new XmlNamespaceManager(lSerializedDocument.NameTable);

            lManager.AddNamespace("sch", "http://purl.oclc.org/dsdl/schematron");

            XmlNode lPhaseNode =
                lSerializedDocument.SelectSingleNode(string.Format("/sch:schema/sch:phase[@id='{0}']", lMockPhase1.ID),
                                                     lManager);

            Assert.IsNotNull(lPhaseNode, "Phase node was not located in the document");
            XmlNode lActiveNode = lPhaseNode.FirstChild;

            Assert.IsNull(lActiveNode, "Active node was not created properly on Phase node");
        }
Ejemplo n.º 2
0
 public Rule FindRule(SchematronDocument a, string id)
 {
     foreach (Pattern p in a.Patterns)
      {
     foreach (Rule r in p.Rules)
     {
        if (r.ID == id)
           return r;
     }
      }
      throw new Exception(String.Format("'{0}' is not a rule.", id));
 }
Ejemplo n.º 3
0
        internal virtual string SerializeSchematronDocument(SchematronDocument doc, Dictionary <string, string> namespaces)
        {
            var ser = new SchematronDocumentSerializer();

            // Add the namespaces to the serializer
            foreach (string cPrefix in namespaces.Keys)
            {
                ser.AddNamespace(cPrefix, namespaces[cPrefix]);
            }

            var output = ser.SerializeDocument(doc);

            return(output);
        }
Ejemplo n.º 4
0
        public string SerializeDocument(SchematronDocument aDocument)
        {
            this.CreateHeaderAndRoot();

            // Phases must be placed at the top of the document
            this.RegisterPhases(aDocument.Phases);

            // Patterns must be placed after all of the phases
            foreach (Phase lCurrentPhase in aDocument.Phases)
            {
                this.RegisterPatterns(lCurrentPhase.ActivePatterns);
            }

            return(this.CreateXmlString());
        }
Ejemplo n.º 5
0
 public void ReadingISO()
 {
     SchematronDocument doc = new SchematronDocument();
      doc.Load("Schematron/Samples/AllISO.sch");
      Assertion a = doc.Patterns["testing"].Rules["foo"].Assertions[0];
      Assert.AreEqual("diag-1", a.Diagnostics);
      Assert.AreEqual("flag", a.Flag);
      Assert.AreEqual("fpi", a.Fpi);
      Assert.AreEqual("icon", a.Icon);
      Assert.AreEqual("foo-rule", a.ID);
      Assert.AreEqual("foo must be bar", a.Message.ToString());
      Assert.AreEqual("role", a.Role);
      Assert.AreEqual("see", a.See);
      Assert.AreEqual("subject", a.Subject);
      Assert.AreEqual(". = 'bar'", a.Test);
 }
Ejemplo n.º 6
0
        public void MinimalIsValid()
        {
            SchematronDocument full = SchematronReader.ReadSchematron("Schematron/Samples/All.sch");
             SchematronDocument minimal = new Compiler().Compile(full);
             StringBuilder schematron = new StringBuilder();
             minimal.Save(schematron);

             XmlDocument minimalDocument = new XmlDocument();
             minimalDocument.LoadXml(schematron.ToString());

             SchematronValidator validator = new SchematronValidator(Schematron.Default.IsoSchematronSchema);
             validator.ValidationPhase = "minimal";
             validator.Validate(minimalDocument);

             SchematronDocument minimal2 = new SchematronDocument();
             minimal2.Load(schematron);
        }
Ejemplo n.º 7
0
        public void EmptyDocument_NoException()
        {
            SchematronDocument           lDocument = new SchematronDocument();
            SchematronDocumentSerializer lBuilder  = new SchematronDocumentSerializer();
            string lSerializedModel = lBuilder.SerializeDocument(lDocument);

            Assert.IsFalse(string.IsNullOrEmpty(lSerializedModel),
                           "A valid but empty document (root element only) was not created");

            XmlDocument lSerializedDocument = new XmlDocument();

            lSerializedDocument.LoadXml(lSerializedModel);

            XmlNamespaceManager lManager = new XmlNamespaceManager(lSerializedDocument.NameTable);

            lManager.AddNamespace("sch", "http://www.ascc.net/xml/schematron");

            XmlNode lPhaseNode =
                lSerializedDocument.SelectSingleNode("/schema/sch:phase", lManager);

            Assert.IsNull(lPhaseNode, "Phase node was not located in the document");
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Generates a schematron xml (string) for the given IG in the database.
        /// </summary>
        /// <returns>Returns a string representing the generated schematron document (XML).</returns>
        public string Generate()
        {
            if (ig == null)
            {
                return(null); //thow an exception?
            }
            // Clear the cloned constraints whenever we run generate so that we don't get duplicate exceptions
            this.clonedConstraints.Clear();

            var errorPhase = new Phase()
            {
                ID = "errors"
            };
            var warningPhase = new Phase()
            {
                ID = "warnings"
            };
            var schematronDocument = new SchematronDocument();

            if (this.includeCustom)
            {
                IEnumerable <ImplementationGuideSchematronPattern> customErrorPatterns   = ig.SchematronPatterns.Where(y => y.Phase == "errors");
                IEnumerable <ImplementationGuideSchematronPattern> customWarningPatterns = ig.SchematronPatterns.Where(y => y.Phase == "warnings");

                AddCustomPatterns(errorPhase, customErrorPatterns);
                AddCustomPatterns(warningPhase, customWarningPatterns);
            }

            // TRIF-909: Remove closed template rules from Trifolia Schematron generation
            //AddDocumentLevelTemplateConstraints(this.ig, errorPhase);

            foreach (var template in templates)
            {
                try
                {
                    AddTemplate(template, errorPhase, warningPhase);

                    if (!template.IsOpen)
                    {
                        AddClosedTemplateConstraints(template, errorPhase);
                    }
                }
                catch (Exception ex)
                {
                    Log.For(this).Error("Error generating schematron for template {0} ({1})", ex, template.Name, template.Oid);
                    throw new Exception(
                              string.Format(
                                  "Unknown error occurred while generating schematron at {0}. Please notify a system administrator of this error.",
                                  DateTime.Now.ToShortTimeString()), ex);
                }
            }

            schematronDocument.Phases.Add(errorPhase);
            schematronDocument.Phases.Add(warningPhase);

            // Prepare a list of namespaces to add to the schematron document
            var namespacesList = (from t in templates
                                  join tt in this.rep.TemplateTypes on t.TemplateTypeId equals tt.Id
                                  join igt in this.rep.ImplementationGuideTypes on tt.ImplementationGuideTypeId equals igt.Id
                                  select new { Prefix = igt.SchemaPrefix, URI = igt.SchemaURI }).Distinct();

            Dictionary <string, string> namespaces = new Dictionary <string, string>();

            foreach (var cNamespaceItem in namespacesList)
            {
                namespaces.Add(cNamespaceItem.Prefix, cNamespaceItem.URI);
            }

            return(SerializeSchematronDocument(schematronDocument, namespaces));
        }
Ejemplo n.º 9
0
        public void BuildAdvanceDirectiveObservationDocument_1stLevelOnly()
        {
            var sectionCount = 1;
            var phase        = new Phase();

            phase.ID = "error";
            var document = new SchematronDocument();

            document.Phases.Add(phase);


            var doc = new DocumentTemplate("cda");

            doc.AddElement(new DocumentTemplateElement("observation"));
            doc.ChildElements[0].AddAttribute(new DocumentTemplateElementAttribute("classCode", "OBS"));
            doc.ChildElements[0].AddAttribute(new DocumentTemplateElementAttribute("moodCode", "EVN"));
            doc.AddElement(new DocumentTemplateElement("templateId"));
            doc.ChildElements[1].AddAttribute(new DocumentTemplateElementAttribute("root", "2.16.840.1.113883.10.20.22.4.48"));
            doc.AddElement(new DocumentTemplateElement("id"));
            doc.AddElement(new DocumentTemplateElement("code"));
            doc.ChildElements[doc.ChildElements.Count - 1].AddAttribute(new DocumentTemplateElementAttribute("xsi-type", "CE", "2.16.840.1.113883.1.11.20.2"));
            doc.AddElement(new DocumentTemplateElement("statusCode"));
            doc.ChildElements[doc.ChildElements.Count - 1].AddAttribute(new DocumentTemplateElementAttribute("code", "completed", "2.16.840.1.113883.5.14"));
            var participantElement = new DocumentTemplateElement("participant");

            doc.ChildElements[0].AddElement(participantElement);
            participantElement.AddAttribute(new DocumentTemplateElementAttribute("typeCode", "VRF"));
            var templateIdElement = new DocumentTemplateElement("templateId");

            templateIdElement.AddAttribute(new DocumentTemplateElementAttribute("root", "2.16.840.1.113883.10.20.1.58"));
            participantElement.AddElement(templateIdElement);
            var timeElement = new DocumentTemplateElement("time");

            timeElement.AddAttribute(new DocumentTemplateElementAttribute("xsi:type", "TS"));
            participantElement.AddElement(timeElement);
            var participantRoleElement = new DocumentTemplateElement("participantRole");

            participantElement.AddElement(participantRoleElement);


            var contextBuilder = new ContextBuilder(doc.ChildElements[0], "cda");
            var rule           = new Rule();

            rule.Context = contextBuilder.GetFullyQualifiedContextString();

            var assertionBuilder = new AssertionLineBuilder(doc.ChildElements[0].Attributes[0], templateIdentifierXpath, templateVersionIdentifierXpath);  //"OBS"

            rule.Assertions.Add(new Assertion()
            {
                AssertionMessage = "SHALL contain 1..1 @classCode='OBS' Observation (CodeSystem: HL7ActClass 2.16.840.1.113883.5.6) (CONF:8648).",
                Test             = assertionBuilder.WithCardinality(CardinalityParser.Parse("1..1")).WithinContext(contextBuilder.GetRelativeContextString()).ConformsTo(Conformance.SHALL).ToString()
            });

            assertionBuilder = new AssertionLineBuilder(doc.ChildElements[0].Attributes[1], templateIdentifierXpath, templateVersionIdentifierXpath);  //"EVN"
            rule.Assertions.Add(new Assertion()
            {
                AssertionMessage = "SHALL contain 1..1 @moodCode='EVN' Event (CodeSystem: ActMood 2.16.840.1.113883.5.1001) (CONF:8649).",
                Test             = assertionBuilder.WithCardinality(CardinalityParser.Parse("1..1")).WithinContext(contextBuilder.GetRelativeContextString()).ConformsTo(Conformance.SHALL).ToString()
            });
            var pattern = new Pattern();

            pattern.ID   = sectionCount.ToString();
            pattern.Name = string.Format("pattern-{0}-errors", pattern.ID);
            pattern.Rules.Add(rule);
            phase.ActivePatterns.Add(pattern);

            rule             = new Rule();
            contextBuilder   = new ContextBuilder(doc.ChildElements[1], "cda");
            rule.Context     = contextBuilder.GetFullyQualifiedContextString();
            assertionBuilder = new AssertionLineBuilder(doc.ChildElements[1], templateIdentifierXpath, templateVersionIdentifierXpath);  //"templateId[@rootCode]"
            rule.Assertions.Add(new Assertion()
            {
                AssertionMessage = "SHALL contain 1..1 @root='2.16.840.1.113883.10.20.22.4.48' (CONF:10485).",
                Test             = assertionBuilder.WithCardinality(CardinalityParser.Parse("1..1")).WithinContext(contextBuilder.GetRelativeContextString()).ConformsTo(Conformance.SHALL).ToString()
            });

            sectionCount++;
            pattern      = new Pattern();
            pattern.ID   = sectionCount.ToString();
            pattern.Name = string.Format("pattern-{0}-errors", pattern.ID);
            pattern.Rules.Add(rule);
            phase.ActivePatterns.Add(pattern);

            rule             = new Rule();
            contextBuilder   = new ContextBuilder(doc.ChildElements[2], "cda");
            rule.Context     = contextBuilder.GetFullyQualifiedContextString();
            assertionBuilder = new AssertionLineBuilder(doc.ChildElements[2], templateIdentifierXpath, templateVersionIdentifierXpath);  //"1..* id"
            rule.Assertions.Add(new Assertion()
            {
                AssertionMessage = "SHALL contain 1..* id (CONF:8654)",
                Test             = assertionBuilder.WithCardinality(CardinalityParser.Parse("1..*")).WithinContext(contextBuilder.GetRelativeContextString()).ConformsTo(Conformance.SHALL).ToString()
            });

            sectionCount++;
            pattern      = new Pattern();
            pattern.ID   = sectionCount.ToString();
            pattern.Name = string.Format("pattern-{0}-errors", pattern.ID);
            pattern.Rules.Add(rule);
            phase.ActivePatterns.Add(pattern);

            rule             = new Rule();
            contextBuilder   = new ContextBuilder(doc.ChildElements[3], "cda");
            rule.Context     = contextBuilder.GetFullyQualifiedContextString();
            assertionBuilder = new AssertionLineBuilder(doc.ChildElements[3], templateIdentifierXpath, templateVersionIdentifierXpath);  //"1..1 code @xsi:type='CE' valueset = 2.16.840.1.113883.1.11.20.2"
            rule.Assertions.Add(new Assertion()
            {
                AssertionMessage = "SHALL contain 1..1 code with @xsi:type='CE', where the @code SHOULD be selected from ValueSet AdvanceDirectiveTypeCode 2.16.840.1.113883.1.11.20.2 STATIC 2006-10-17 (CONF:8651).",
                Test             = assertionBuilder.WithCardinality(CardinalityParser.Parse("1..1")).WithinContext(contextBuilder.GetRelativeContextString()).ConformsTo(Conformance.SHALL).ToString()
            });

            sectionCount++;
            pattern      = new Pattern();
            pattern.ID   = sectionCount.ToString();
            pattern.Name = string.Format("pattern-{0}-errors", pattern.ID);
            pattern.Rules.Add(rule);
            phase.ActivePatterns.Add(pattern);

            rule             = new Rule();
            contextBuilder   = new ContextBuilder(doc.ChildElements[3], "cda");
            rule.Context     = contextBuilder.GetFullyQualifiedContextString();
            assertionBuilder = new AssertionLineBuilder(doc.ChildElements[3], templateIdentifierXpath, templateVersionIdentifierXpath);  //"1..1 statusCode @code='completed' valueset = 2.16.840.1.113883.1.11.20.2"
            rule.Assertions.Add(new Assertion()
            {
                AssertionMessage = "SHALL contain 1..1 code with @xsi:type='CE', where the @code SHOULD be selected from ValueSet AdvanceDirectiveTypeCode 2.16.840.1.113883.1.11.20.2 STATIC 2006-10-17 (CONF:8651).",
                Test             = assertionBuilder.WithCardinality(CardinalityParser.Parse("1..1")).WithinContext(contextBuilder.GetRelativeContextString()).ConformsTo(Conformance.SHALL).ToString()
            });

            sectionCount++;
            pattern      = new Pattern();
            pattern.ID   = sectionCount.ToString();
            pattern.Name = string.Format("pattern-{0}-errors", pattern.ID);
            pattern.Rules.Add(rule);
            phase.ActivePatterns.Add(pattern);

            rule           = new Rule();
            contextBuilder = new ContextBuilder(doc.ChildElements[1].Attributes[0], "cda");
            rule.Context   = contextBuilder.GetFullyQualifiedContextString();
            var childtemplateIdElementAssertionBuilder = new AssertionLineBuilder(templateIdElement.Attributes[0], templateIdentifierXpath, templateVersionIdentifierXpath)  //templateId/@root
                                                         .WithCardinality(CardinalityParser.Parse("1..1"))
                                                         .ConformsTo(Conformance.SHALL)
                                                         .WithinContext("cda:");
            var childParticipantElementAssertionBuilder = new AssertionLineBuilder(participantRoleElement, templateIdentifierXpath, templateVersionIdentifierXpath)
                                                          .WithCardinality(CardinalityParser.Parse("1..*"))
                                                          .ConformsTo(Conformance.SHALL)
                                                          .WithinContext("cda:");
            var childTimeElementAssertionBuilder = new AssertionLineBuilder(timeElement, templateIdentifierXpath, templateVersionIdentifierXpath)
                                                   .WithCardinality(CardinalityParser.Parse("0..1"))
                                                   .ConformsTo(Conformance.SHOULD)
                                                   .WithinContext("cda:");

            assertionBuilder = new AssertionLineBuilder(participantElement, templateIdentifierXpath, templateVersionIdentifierXpath);  //participant
            rule.Assertions.Add(new Assertion()
            {
                AssertionMessage = "should contain 1..* participant (CONF:8662), participant should contain 0..1 time (CONF:8665), the data type of Observation/participant/time in a verification SHALL be TS (time stamp) (CONF:8666), participant shall contain 1..1 participantRole (CONF:8825), participant shall contain 1..1 @typeCode=VRF 'Verifier' (CodeSystem: 2.16.840.1.113883.5.90) (CONF:8663), participant shall contain 1..1 templateId (CONF:8664), templateId shall contain 1..1 @root=2.16.840.1.113883.10.20.1.58 (CONF:10486)",
                Test             = assertionBuilder
                                   .WithCardinality(CardinalityParser.Parse("1..*"))
                                   .WithinContext("cda:")
                                   .ConformsTo(Conformance.SHALL)
                                   .WithChildElementBuilder(childTimeElementAssertionBuilder)
                                   .WithChildElementBuilder(childParticipantElementAssertionBuilder)
                                   .WithChildElementBuilder(childtemplateIdElementAssertionBuilder)
                                   .ToString()
            });

            sectionCount++;
            pattern      = new Pattern();
            pattern.ID   = sectionCount.ToString();
            pattern.Name = string.Format("pattern-{0}-errors", pattern.ID);
            pattern.Rules.Add(rule);
            phase.ActivePatterns.Add(pattern);

            var    builder         = new SchematronDocumentSerializer();
            string serializedModel = builder.SerializeDocument(document);

            Assert.IsFalse(string.IsNullOrEmpty(serializedModel), "No string returned from serialize document");

            string[] lModelLines = serializedModel.Split('\n');
            Assert.IsNotNull(lModelLines, "The generated string was not split on lines");
            Assert.IsTrue(lModelLines.Length > 1, "The generated string was not split on lines");
        }
Ejemplo n.º 10
0
        public void ValidSchematronDocument_1Rule_1Assertion_ValidSchematronDocumentEmitted()
        {
            Assertion lMockAssertion = new Assertion();

            lMockAssertion.AssertionMessage = "This test fails";
            lMockAssertion.Test             = "count(@code) > 1";

            Rule lRule = new Rule();

            lRule.Assertions.Add(lMockAssertion);
            lRule.Context = "cda:code";

            Pattern lPattern = new Pattern();

            lPattern.ID   = "pattern1";
            lPattern.Name = "mock-pattern";
            lPattern.Rules.Add(lRule);

            Phase lMockPhase1 = new Phase();

            lMockPhase1.ID = "error";
            lMockPhase1.ActivePatterns.Add(lPattern);

            SchematronDocument lDocument = new SchematronDocument();

            lDocument.Phases.Add(lMockPhase1);

            SchematronDocumentSerializer lBuilder = new SchematronDocumentSerializer();
            string lSerializedModel = lBuilder.SerializeDocument(lDocument);

            Assert.IsFalse(string.IsNullOrEmpty(lSerializedModel), "A valid Schematron document was not created!");

            XmlDocument lSerializedDocument = new XmlDocument();

            lSerializedDocument.LoadXml(lSerializedModel);

            XmlNamespaceManager lManager = new XmlNamespaceManager(lSerializedDocument.NameTable);

            lManager.AddNamespace("sch", "http://purl.oclc.org/dsdl/schematron");

            XmlNode lPhaseNode =
                lSerializedDocument.SelectSingleNode(string.Format("/sch:schema/sch:phase[@id='{0}']", lMockPhase1.ID),
                                                     lManager);

            Assert.IsNotNull(lPhaseNode, "Phase node was not located in the document");

            XmlNode lActiveNode = lPhaseNode.FirstChild;

            Assert.IsNotNull(lActiveNode, "Active node was not created properly on Phase node");
            Assert.IsNotNull(lActiveNode.Attributes, "Active node attributes were not created properly");

            var lExistingAttributes = from XmlAttribute a in lActiveNode.Attributes
                                      where a.Name.Equals("pattern", StringComparison.InvariantCultureIgnoreCase)
                                      select a;

            Assert.IsNotNull(lExistingAttributes, "Active node did not contain an attribute named 'pattern'");
            Assert.IsTrue(lExistingAttributes.Any(), "Active node did not contain an attribute named 'pattern'");
            Assert.AreEqual("pattern1", lActiveNode.Attributes["pattern"].Value, "Pattern attribute on Active was invalid");

            XmlNode lPatternNode =
                lSerializedDocument.SelectSingleNode(string.Format("/sch:schema/sch:pattern[@id='{0}']", lPattern.ID),
                                                     lManager);

            Assert.IsNotNull(lPatternNode, "The desired pattern node was not found");

            XmlNode lRuleNode =
                lSerializedDocument.SelectSingleNode(
                    string.Format("/sch:schema/sch:pattern[@id='{0}']/sch:rule[@context='{1}']", lPattern.ID, lRule.Context),
                    lManager);

            Assert.IsNotNull(lRuleNode, "The rule node did not exist in the pattern node");
        }
Ejemplo n.º 11
0
        /// <summary>
        /// <see cref="SchemaValidator"/> static constructor with an enumerated schematron content for NHS messages)
        /// </summary>
        /// <param name="schematronDocument">Enumerated schematron content, the resources is contained wihtin Messaging.Core assembly</param>
        /// <returns></returns>

        public static SchematronValidator Create(SchematronDocument schematronDocument) =>
        schematronDocument switch
        {