Example #1
0
        private void AddInformant(Composition header, XElement element)
        {
            if (header == null || element == null)
            {
                return;
            }

            foreach (var entity in element.Elements())
            {
                if (entity.Name.LocalName == "assignedEntity")
                {
                    var practitioner = FromXml(new PractitionerParser(Bundle), entity);

                    if (practitioner != null)
                    {
                        header.AddExtension("http://hl7.org/fhir/us/ccda/StructureDefinition/CCDA-on-FHIR-Informant",
                                            practitioner.GetResourceReference());
                    }
                }
                else if (entity.Name.LocalName == "relatedEntity")
                {
                    var relatedPerson = FromXml(new RelatedPersonParser(Bundle), entity);

                    if (relatedPerson != null)
                    {
                        relatedPerson.Patient = header.Subject;
                        header.AddExtension("http://hl7.org/fhir/us/ccda/StructureDefinition/CCDA-on-FHIR-Informant",
                                            relatedPerson.GetResourceReference());
                    }
                }
            }
        }
Example #2
0
        public override Bundle FromXml(XElement rootElement)
        {
            if (rootElement == null)
            {
                Errors.Add(new ParserError("XML Document doesn't have a root", ParseErrorLevel.Error));
                return(null);
            }

            // Not a CDA xml
            if (rootElement.Name.LocalName != "ClinicalDocument")
            {
                Errors.Add(new ParserError("XML Document's root is not ClinicalDocument", ParseErrorLevel.Error));
                return(null);
            }


            Bundle = new Bundle
            {
                Id   = Guid.NewGuid().ToString(),
                Type = Bundle.BundleType.Document
            };

            var header = new Composition
            {
                Id     = Guid.NewGuid().ToString(),
                Meta   = new Meta(),
                Status = CompositionStatus.Final
            };

            Bundle.AddResourceEntry(header);

            foreach (var child in rootElement.Elements())
            {
                switch (child.Name.LocalName)
                {
                case "id":
                    Bundle.Identifier = FromXml(new IdentifierParser(), child);
                    break;

                case "code":
                    AddCode(header, child);
                    break;

                case "title":
                    header.Title = child.Value;
                    break;

                case "effectiveTime":
                    header.DateElement = FromXml(new FhirDateTimeParser(), child);
                    break;

                case "confidentialityCode":
                    var confidentialityCode = FromXml(new CodeParser(), child)?.Value;
                    if (!string.IsNullOrEmpty(confidentialityCode) && Enum.TryParse(confidentialityCode, true,
                                                                                    out Composition.ConfidentialityClassification confidentialityClassification))
                    {
                        header.Confidentiality = confidentialityClassification;
                    }
                    break;

                case "languageCode":
                    header.Language = FromXml(new CodeParser(), child)?.Value;
                    break;

                case "setId":
                    header.Identifier = FromXml(new IdentifierParser(), child);
                    break;

                case "recordTarget":
                    var patient = FromXml(new PatientParser(Bundle), child.CdaElement("patientRole"));
                    if (patient != null)
                    {
                        header.Subject = patient.GetResourceReference();
                    }
                    break;

                case "author":
                    AddAuthor(header, child);
                    break;

                case "dataEnterer":
                    var dataEnterer = FromXml(new PractitionerParser(Bundle), child.CdaElement("assignedEntity"));
                    if (dataEnterer != null)
                    {
                        header.AddExtension(
                            "http://hl7.org/fhir/us/ccda/StructureDefinition/CCDA-on-FHIR-Data-Enterer",
                            dataEnterer.GetResourceReference());
                    }
                    break;

                case "informant":
                    AddInformant(header, child);
                    break;

                case "custodian":
                    var custodian = FromXml(new OrganizationParser(Bundle),
                                            child.CdaElement("assignedCustodian")
                                            ?.CdaElement("representedCustodianOrganization"));

                    if (custodian != null)
                    {
                        header.Custodian = custodian.GetResourceReference();
                    }
                    break;

                case "informationRecipient":
                    var infoRecipient = FromXml(new PractitionerParser(Bundle),
                                                child.CdaElement("intendedRecipient"));
                    if (infoRecipient != null)
                    {
                        header.AddExtension(
                            "http://hl7.org/fhir/us/ccda/StructureDefinition/CCDA-on-FHIR-Information-Recipient",
                            infoRecipient.GetResourceReference());
                    }
                    break;

                case "legalAuthenticator":
                    AddAuthenticator(header, child, Composition.CompositionAttestationMode.Legal);
                    break;

                case "authenticator":
                    AddAuthenticator(header, child,
                                     Composition.CompositionAttestationMode.Professional);
                    break;

                case "participant":
                    var participant = FromXml(new RelatedPersonParser(Bundle),
                                              child.CdaElement("associatedEntity"));
                    if (participant != null)
                    {
                        header.AddExtension(
                            "http://hl7.org/fhir/us/ccda/StructureDefinition/CCDA-on-FHIR-Participant",
                            participant.GetResourceReference());
                    }
                    break;

                case "documentationOf":
                    AddServiceEvent(header, child.CdaElement("serviceEvent"));
                    break;

                case "component":
                    foreach (var sectionElement in child.CdaDescendants("section"))
                    {
                        AddSection(header, sectionElement);
                    }
                    break;
                }
            }

            if (ParserSettings.RunValidation)
            {
                var settings = new ValidationSettings
                {
                    ResourceResolver = new CachedResolver(new MultiResolver(
                                                              new ZipSource("Definitions/stu3-definitions.xml.zip"),
                                                              new ZipSource("Definitions/us-core-definitions.xml.zip"),
                                                              new ZipSource("Definitions/ccda-on-fhir-definitions.xml.zip")
                                                              ))
                };
                var validator = new Validator(settings);

                var outcome = validator.Validate(Bundle);

                foreach (var issue in outcome.Issue)
                {
                    Errors.Add(new ParserError(issue.Details.Text, ParseErrorLevel.Error));
                }
            }

            return(Bundle);
        }