예제 #1
0
        public void GenerateSchematronAssertion_Element_ValueSet_SVS_ConformanceSHALL_CardinalityOneToOne()
        {
            var element = new DocumentTemplateElement("administrativeGenderCode");
            //create schematron assertion line builder, build one at a time (regular interface, see above for fluent interface)
            var builder = new AssertionLineBuilder(element, templateIdentifierXpath, templateVersionIdentifierXpath);
            //define cardinality
            var cardinality = CardinalityParser.Parse("1..1");

            //add cardinality for the element
            builder.WithCardinality(cardinality);
            //define conformance
            var conformance = ConformanceParser.Parse("SHALL");

            //add conformance for the element
            builder.ConformsTo(conformance);
            builder.WithinValueSet("4.3.2.1", VocabularyOutputType.SVS_SingleValueSet);
            //generate string
            string assertion = builder.ToString();
            //did we generate the correct string?
            string expected = @"count(administrativeGenderCode[@code=document('4.3.2.1.xml')/svs:RetrieveValueSetResponse/svs:ValueSet[@id='4.3.2.1']/svs:ConceptList/svs:Concept/@code])=1";

            Assert.IsTrue(assertion == expected, "Assertion string was not correct. Expected '{0}', Actual '{1}'.", expected, assertion);
        }
        public void GenerateSchematronAssertion_Element_ConformanceSHALL_CardinalityOneToOne()
        {
            //create cda doc
            var cdaDocumentTemplate = new DocumentTemplate("urn:hl7-org:v3");
            //create code element
            var element = new DocumentTemplateElement("code");

            //add element to doc
            cdaDocumentTemplate.AddElement(element);
            //create schematron assertion line builder
            var builder = new AssertionLineBuilder(this.tdb, element, this.igType, this.igTypeSchema);
            //define cardinality and conformance
            var cardinality = CardinalityParser.Parse("1..1");
            var conformance = ConformanceParser.Parse("SHALL");

            //add element (context comes from doc), conformance, cardinality through fluent interface
            builder.ConformsTo(conformance).WithCardinality(cardinality);
            //generate string
            string assertion = builder.ToString();

            //did we generate the correct string?
            Assert.IsTrue(assertion == @"count(cda:code)=1", "The generated assertion was not correct. Expected 'count(cda:code)=1', Actual '{0}'.", assertion);
        }
예제 #3
0
        public void GenerateSchematronAssertion_Element_With_Value_ConformanceSHALL_CardinalityOneToOne()
        {
            //create cda doc
            var cdaDocumentTemplate = new DocumentTemplate("urn:hl7-org:v3");
            //create code element
            var element = new DocumentTemplateElement("code", "Test");

            //add element to doc
            cdaDocumentTemplate.AddElement(element);
            //create schematron assertion line builder
            var builder = new AssertionLineBuilder(element, templateIdentifierXpath, templateVersionIdentifierXpath, "cda");
            //define cardinality and conformance
            var cardinality = CardinalityParser.Parse("1..1");
            var conformance = ConformanceParser.Parse("SHALL");

            //add element (context comes from doc), conformance, cardinality through fluent interface
            builder.ConformsTo(conformance).WithCardinality(cardinality);
            //generate string
            string assertion = builder.ToString();

            //did we generate the correct string?
            Assert.IsTrue(assertion == @"count(cda:code[translate(text(), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')='test'])=1", "The generated assertion was not correct. Expected 'count(cda:code[text()='Test'])=1', Actual '{0}'.", assertion);
        }
        public void GenerateSchematronAssertion_NamespaceEMA_Element_Template_ConformanceSHALL_CardinalityOneToOne()
        {
            //create cda doc
            var cdaDocumentTemplate = new DocumentTemplate("urn:hl7-org:v3");
            //create code element
            var element = new DocumentTemplateElement("encounter");

            //add element to doc
            cdaDocumentTemplate.AddElement(element);
            //create schematron assertion line builder
            var builder = new AssertionLineBuilder(this.tdb, element, this.igType, this.igTypeSchema, "ema");
            //define cardinality and conformance
            var cardinality = CardinalityParser.Parse("1..1");
            var conformance = ConformanceParser.Parse("SHALL");

            //add element (context comes from doc), conformance, cardinality through fluent interface
            builder.ConformsTo(conformance).WithCardinality(cardinality).ContainsTemplate("urn:oid:4.3.2.1", "Section");
            //generate string
            string assertion = builder.ToString();
            string expected  = @"count(ema:encounter[ema:templateId[@root='4.3.2.1']])=1";

            //did we generate the correct string?
            Assert.IsTrue(assertion == expected, "The generated assertion was not correct. Expected '{0}', Actual '{1}'.", expected, assertion);
        }
        public void GenerateSchematronAssertion_Attribute_Valueset_ConformanceMAY_CardinalityOneToOne()
        {
            var attr = new DocumentTemplateElementAttribute("moodCode", "EVN");
            //create schematron assertion line builder, build one at a time (regular interface, see above for fluent interface)
            var builder = new AssertionLineBuilder(this.tdb, attr, this.igType, this.igTypeSchema);
            //define cardinality
            var cardinality = CardinalityParser.Parse("1..1");

            //add cardinality for the element
            builder.WithCardinality(cardinality);
            //define conformance
            var conformance = ConformanceParser.Parse("MAY");

            //add conformance for the element
            builder.ConformsTo(conformance);
            //add valueset
            builder.WithinValueSet("2.16.840.1.113883.1.11.20.2");
            //generate string
            string assertion = builder.ToString();
            //did we generate the correct string?
            string expected = "@moodCode='EVN' and @moodCode=document('the_voc.xml')/voc:systems/voc:system[@valueSetOid='2.16.840.1.113883.1.11.20.2']/voc:code/@value";

            Assert.IsTrue(assertion == expected, "Assertion string was not correct. Expected empty string, Actual '{1}'.", expected, assertion);
        }
예제 #6
0
        public void GenerateSchematronAssertion_Element_ConformanceSHALL_CardinalityZeroToMany()
        {
            //create cda doc
            var cdaDocumentTemplate = new DocumentTemplate("urn:hl7-org:v3");
            //create code element
            var element = new DocumentTemplateElement("code");

            //add element to doc
            cdaDocumentTemplate.AddElement(element);
            //create schematron assertion line builder
            var builder = new AssertionLineBuilder(element, templateIdentifierXpath, templateVersionIdentifierXpath);
            //define cardinality and conformance
            var cardinality = CardinalityParser.Parse("0..*");
            var conformance = ConformanceParser.Parse("SHALL");

            //add element (context comes from doc), conformance, cardinality through fluent interface
            builder.ConformsTo(conformance).WithCardinality(cardinality);
            //generate string
            string assertion = builder.ToString();
            string expected  = "not(code) or code";

            //did we generate the correct string?
            Assert.IsTrue(assertion == expected, "The generated assertion was not correct. Expected '{0}', Actual '{1}'.", expected, assertion);
        }
예제 #7
0
        public ConstraintParser(IObjectRepository tdb, IConstraint constraint, ImplementationGuideType igType, string valueSetFile = "voc.xml", VocabularyOutputType vocabularyOutputType = VocabularyOutputType.Default)
        {
            this.tdb          = tdb;
            this.constraint   = constraint;
            this.valueSetFile = valueSetFile;
            this.igTypePlugin = igType.GetPlugin();

            if (this.constraint.ValueSetId != null)
            {
                this.constraintValueSet = this.tdb.ValueSets.Single(y => y.Id == constraint.ValueSetId);
            }

            if (this.constraint.ValueCodeSystemId != null)
            {
                this.constraintCodeSystem = this.tdb.CodeSystems.Single(y => y.Id == constraint.ValueCodeSystemId);
            }

            if (!string.IsNullOrEmpty(this.constraint.Cardinality))
            {
                this.constraintCardinalityType = CardinalityParser.Parse(this.constraint.Cardinality);
            }

            if (!string.IsNullOrEmpty(this.constraint.Conformance))
            {
                this.constraintConformanceType = ConformanceParser.Parse(this.constraint.Conformance);
            }

            if (this.constraint.ContainedTemplateId != null)
            {
                this.containedTemplate = this.tdb.Templates.Single(y => y.Id == this.constraint.ContainedTemplateId.Value);
            }

            this.prefix = igType.SchemaPrefix;

            this.vocabularyOutputType = vocabularyOutputType;
        }
예제 #8
0
        /// <summary>
        /// This is the main public interface for constraint parser. Takes the given constraint and builds an AssertionLineBuilder, applying the values, attributes, context, etc as necessary.
        /// </summary>
        /// <returns>
        /// AssertionLineBuilder representing the values from the constraint given to the parser.
        /// </returns>
        public AssertionLineBuilder CreateAssertionLineBuilder()
        {
            if (this.valueSet == null && this.constraint.ValueSetId != null)
            {
                this.valueSet = this.tdb.ValueSets.Single(y => y.Id == constraint.ValueSetId);
            }

            if (this.codeSystem == null && this.constraint.ValueCodeSystemId != null)
            {
                this.codeSystem = this.tdb.CodeSystems.Single(y => y.Id == constraint.ValueCodeSystemId);
            }

            IConstraint currentConstraint  = this.constraint; //set current constraint, setting this as a variable allows us to move the current constraint to the parent when dealing with branches
            var         containedTemplates = currentConstraint.References.Where(y => y.ReferenceType == ConstraintReferenceTypes.Template);

            if (string.IsNullOrEmpty(currentConstraint.Context) && !containedTemplates.Any()) //we can have empty context but a contained template
            {
                return(null);
            }

            DocumentTemplateElement          element   = null;
            DocumentTemplateElementAttribute attribute = null;

            ConstraintToDocumentElementHelper.ParseContextForElementAndAttribute(currentConstraint, out element, out attribute);
            DocumentTemplateElement parentElement =
                ConstraintToDocumentElementHelper.CreateParentElementForAttribute(currentConstraint, attribute);

            string parentContext =
                CreateParentContextForElement(parentElement, element, currentConstraint);

            AssertionLineBuilder asb             = null;
            AssertionLineBuilder branchedRootAsb = null;

            // Determine if we should create the AssertionLineBuilder starting with an attribute or an element.
            if (attribute != null)
            {
                DecorateAttributeFromConstraint(parentContext, attribute, currentConstraint, this.valueSet);
                if (currentConstraint.Parent != null && currentConstraint.IsBranch)
                {
                    branchedRootAsb = CreateBranchedRootAssertionLineBuilderFromConstraint(currentConstraint);
                }
                else
                {
                    asb = CreateAssertionLineBuilderForAttribute(parentElement, attribute, ref parentContext, ref currentConstraint);
                }
            }
            else //this is an element
            {
                // Only add the code system constraints if there is no value conformance or the value conformance matches the element/attribute conformance
                // This is because in the SchematronGenerator class, a duplicate constraint is created when the value conformance is different from
                // the element/attribute conformance, where the duplicate constraint's conformance matches the value conformance.
                if (string.IsNullOrEmpty(currentConstraint.ValueConformance) || ConformanceParser.Parse(currentConstraint.Conformance) == ConformanceParser.Parse(currentConstraint.ValueConformance))
                {
                    ConstraintToDocumentElementHelper.AddCodeSystemToElement(this.tdb, this.igTypePlugin, element, currentConstraint);
                }

                if (currentConstraint.IsBranch)
                {
                    branchedRootAsb = CreateBranchedRootAssertionLineBuilderFromConstraint(currentConstraint);
                    branchedRootAsb.HasParentContext(parentContext);
                }
                else
                {
                    //if we have a context already then we will append it at end so pass in false, else go ahead and generate (pass in true)
                    asb = CreateAssertionLineBuilderForElement(element, this.constraint, ref parentContext, string.IsNullOrEmpty(parentContext));
                }
            }

            if (branchedRootAsb == null) //if this is a branched root then a separate builder was constructed
            {
                ConstraintToDocumentElementHelper.AddConformance(currentConstraint, asb);
                ConstraintToDocumentElementHelper.AddCardinality(currentConstraint, asb);
                // Determine if we have a valueset
                if (this.valueSet != null && currentConstraint.IsValueSetStatic)
                {
                    var requireValueset = true;

                    if (!string.IsNullOrEmpty(currentConstraint.ValueConformance))
                    {
                        if (ConformanceParser.Parse(currentConstraint.Conformance) != ConformanceParser.Parse(currentConstraint.ValueConformance))
                        {
                            requireValueset = false;
                        }
                    }

                    if (requireValueset)
                    {
                        //TODO: Move into CDA specific library
                        //are we bound directly to a code or value element?
                        bool includeNullFlavor = false;
                        if (element != null && attribute == null && (element.ElementName == "value" || element.ElementName == "code"))
                        {
                            includeNullFlavor = true;
                        }

                        string valueSetIdentifier = this.igTypePlugin.ParseIdentifier(this.valueSet.GetIdentifier(this.igTypePlugin));
                        asb.WithinValueSet(valueSetIdentifier, this.valueSetFile, this.vocabularyOutputType, includeNullFlavor);
                    }
                }

                //determine if we have a parent context
                if (!string.IsNullOrEmpty(parentContext))
                {
                    asb.HasParentContext(parentContext);
                    DecorateParentOptionality(asb, currentConstraint);
                }
            }
            else //branched root, use that one instead
            {
                //determine if we have a parent context
                if (!string.IsNullOrEmpty(parentContext))
                {
                    branchedRootAsb.HasParentContext(parentContext);
                    DecorateParentOptionality(branchedRootAsb, currentConstraint);
                }
            }

            return((branchedRootAsb == null) ? asb : branchedRootAsb);
        }