예제 #1
0
        public override HumanName FromXml(XElement element)
        {
            if (element == null)
            {
                return(null);
            }

            var name = new HumanName
            {
                Use = new NameUseParser().FromCda(element.Attribute("use")?.Value)
            };

            foreach (var child in element.Elements())
            {
                switch (child.Name.LocalName)
                {
                case "family":
                    name.Family = child.Value;
                    break;

                case "given":
                    var given = child.Value;
                    if (!string.IsNullOrEmpty(given))
                    {
                        name.GivenElement.Add(new FhirString(given));
                    }
                    break;

                case "prefix":
                    var prefix = child.Value;
                    if (!string.IsNullOrEmpty(prefix))
                    {
                        name.PrefixElement.Add(new FhirString(prefix));
                    }
                    break;

                case "suffix":
                    var suffix = child.Value;
                    if (!string.IsNullOrEmpty(suffix))
                    {
                        name.SuffixElement.Add(new FhirString(suffix));
                    }
                    break;
                }
            }

            if (string.IsNullOrEmpty(name.Family))
            {
                Errors.Add(ParserError.CreateParseError(element, "does NOT have family element", ParseErrorLevel.Error));
                return(null);
            }

            if (!name.Given.Any())
            {
                Errors.Add(ParserError.CreateParseError(element, "does NOT have given element", ParseErrorLevel.Error));
                return(null);
            }

            return(name);
        }
예제 #2
0
        public override Coding FromXml(XElement element)
        {
            if (element == null)
            {
                return(null);
            }

            var code       = element.Attribute("code")?.Value;
            var system     = element.Attribute("codeSystem")?.Value;
            var display    = element.Attribute("displayName")?.Value;
            var nullFlavor = element.Attribute("nullFlavor")?.Value;

            if (!string.IsNullOrEmpty(nullFlavor))
            {
                return(new Coding("http://hl7.org/fhir/v3/NullFlavor", nullFlavor));
            }

            if (string.IsNullOrWhiteSpace(code))
            {
                Errors.Add(ParserError.CreateParseError(element, "does NOT have code attribute", ParseErrorLevel.Error));
                return(null);
            }

            if (string.IsNullOrWhiteSpace(system))
            {
                Errors.Add(ParserError.CreateParseError(element, "does NOT have codeSystem attribute", ParseErrorLevel.Error));
                return(null);
            }

            var systemUri = new OidParser().FromCda(system);

            return(new Coding(systemUri, code, display));
        }
예제 #3
0
        private void AddAuthor(Composition header, XElement element)
        {
            if (header == null || element == null)
            {
                return;
            }

            var assignedAuthorElement = element.CdaElement("assignedAuthor");

            Resource author = null;

            if (assignedAuthorElement.CdaElement("assignedPerson") != null)
            {
                author = FromXml(new PractitionerParser(Bundle), assignedAuthorElement);
            }
            else if (assignedAuthorElement.CdaElement("assignedAuthoringDevice") != null)
            {
                author = FromXml(new DeviceParser(Bundle), assignedAuthorElement);
            }
            else
            {
                Errors.Add(ParserError.CreateParseError(assignedAuthorElement,
                                                        "does NOT have either assignedPerson element or assignedAuthoringDevice element",
                                                        ParseErrorLevel.Error));
            }

            if (author != null)
            {
                header.Author.Add(new ResourceReference($"{author.TypeName}/{author.Id}"));
            }
        }
예제 #4
0
        public override Address FromXml(XElement element)
        {
            if (element == null)
            {
                return(null);
            }

            var addr = new Address
            {
                Use = new AddressUseParser().FromCda(element.Attribute("use")?.Value)
            };

            foreach (var child in element.Elements())
            {
                switch (child.Name.LocalName)
                {
                case "country":
                    addr.Country = child.Value;
                    break;

                case "state":
                    addr.State = child.Value;
                    break;

                case "city":
                    addr.City = child.Value;
                    break;

                case "postalCode":
                    addr.PostalCode = child.Value;
                    break;

                case "streetAddressLine":
                    addr.LineElement.Add(new FhirString(child.Value));
                    break;
                }
            }

            if (string.IsNullOrEmpty(addr.City))
            {
                Errors.Add(ParserError.CreateParseError(element, "does NOT have <city> element", ParseErrorLevel.Warning));
            }

            if (!addr.Line.Any())
            {
                Errors.Add(ParserError.CreateParseError(element, "does NOT have <streetAddressLine> element", ParseErrorLevel.Warning));
            }

            return(addr);
        }
예제 #5
0
        public void AddServiceEvent(Composition header, XElement element)
        {
            if (header == null || element == null)
            {
                return;
            }

            var serviceEvent = new Composition.EventComponent
            {
                Period = new Period()
            };

            foreach (var child in element.Elements())
            {
                switch (child.Name.LocalName)
                {
                case "effectiveTime":
                    serviceEvent.Period.StartElement = FromXml(new FhirDateTimeParser(), child.CdaElement("low"));
                    serviceEvent.Period.EndElement   = FromXml(new FhirDateTimeParser(), child.CdaElement("high"));
                    break;

                case "performer":
                    var performer = FromXml(new PractitionerParser(Bundle), child.CdaElement("assignedEntity"));

                    if (performer != null)
                    {
                        serviceEvent.AddExtension(
                            "http://hl7.org/fhir/us/ccda/StructureDefinition/CCDA-on-FHIR-Performer",
                            performer.GetResourceReference());
                    }
                    break;
                }
            }

            if (serviceEvent.Period?.StartElement == null)
            {
                Errors.Add(ParserError.CreateParseError(element, "does NOT have effectiveTime.low element",
                                                        ParseErrorLevel.Warning));
            }

            header.Event.Add(serviceEvent);
        }
예제 #6
0
        public override Identifier FromXml(XElement element)
        {
            if (element == null)
            {
                return(null);
            }

            var root      = element.Attribute("root")?.Value;
            var extension = element.Attribute("extension")?.Value;

            if (string.IsNullOrEmpty(root))
            {
                Errors.Add(ParserError.CreateParseError(element, "does NOT have root attribute", ParseErrorLevel.Error));
                return(null);
            }

            root = "urn:oid:" + root;

            return(string.IsNullOrEmpty(extension) ? new Identifier("urn:ietf:rfc:3986", root) : new Identifier(root, extension));
        }
예제 #7
0
        public override Date FromXml(XElement element)
        {
            if (element == null)
            {
                return(null);
            }

            var dateString = element.Attribute("value")?.Value;

            if (dateString == null)
            {
                Errors.Add(ParserError.CreateParseError(element, "does NOT have value attribute",
                                                        ParseErrorLevel.Error));
                return(null);
            }

            if (dateString.Length < 4 || dateString.Length > 8)
            {
                Errors.Add(ParserError.CreateParseError(element, "does NOT have valid value attribute",
                                                        ParseErrorLevel.Error));
                return(null);
            }

            var sb = new StringBuilder();

            for (int i = 0; i < dateString.Length; i++)
            {
                if (i == 4 || i == 6)
                {
                    sb.Append("-");
                }

                sb.Append(dateString[i]);
            }

            return(new Date(sb.ToString()));
        }
예제 #8
0
        public override Practitioner FromXml(XElement element)
        {
            if (element == null)
            {
                return(null);
            }

            var practitioner = new Practitioner
            {
                Id   = Guid.NewGuid().ToString(),
                Meta = new Meta
                {
                    Profile = new List <string>
                    {
                        "http://hl7.org/fhir/us/core/StructureDefinition/us-core-practitioner"
                    }
                }
            };

            var role = new PractitionerRole()
            {
                Id           = Guid.NewGuid().ToString(),
                Practitioner = new ResourceReference($"{practitioner.TypeName}/{practitioner.Id}")
            };

            var location = new Location
            {
                Id = Guid.NewGuid().ToString()
            };

            foreach (var child in element.Elements())
            {
                switch (child.Name.LocalName)
                {
                case "id":
                    var id = FromXml(new IdentifierParser(), child);
                    if (id != null)
                    {
                        practitioner.Identifier.Add(id);
                    }
                    break;

                case "code":
                    var code = FromXml(new CodeableConceptParser(), child);
                    if (code != null)
                    {
                        role.Specialty.Add(code);
                    }
                    break;

                case "addr":
                    location.Address = FromXml(new AddressParser(), child);
                    break;

                case "telecom":
                    var telecom = FromXml(new ContactPointParser(), child);
                    if (telecom != null)
                    {
                        location.Telecom.Add(telecom);
                    }
                    break;

                case "assignedPerson":
                case "informationRecipient":
                    var name = FromXml(new HumanNameParser(), child.CdaElement("name"));
                    if (name != null)
                    {
                        practitioner.Name.Add(name);
                    }
                    break;

                case "receivedOrganization":
                    break;
                }
            }

            if (!practitioner.Identifier.Any())
            {
                Errors.Add(ParserError.CreateParseError(element, "does NOT have identifier", ParseErrorLevel.Error));
            }

            if (!practitioner.Name.Any())
            {
                Errors.Add(ParserError.CreateParseError(element, "does NOT have name", ParseErrorLevel.Warning));
            }

            var existingPractitioner = Bundle?.FirstOrDefault <Practitioner>(p => p.Identifier.IsExactly(practitioner.Identifier));

            if (existingPractitioner != null)
            {
                practitioner = existingPractitioner;
            }
            else
            {
                Bundle?.AddResourceEntry(practitioner);
            }

            role.Practitioner = practitioner.GetResourceReference();

            if (location.Address != null || location.Telecom.Any())
            {
                var existingLocation = Bundle?.FirstOrDefault <Location>(l =>
                                                                         l.Address.IsExactly(location.Address) && l.Telecom.IsExactly(location.Telecom));

                if (existingLocation != null)
                {
                    location = existingLocation;
                }
                else
                {
                    Bundle?.AddResourceEntry(location);
                }

                role.Location.Add(location.GetResourceReference());
            }

            var existingRole = Bundle?.FirstOrDefault <PractitionerRole>(pr =>
                                                                         pr.Location.IsExactly(role.Location) &&
                                                                         pr.Specialty.IsExactly(role.Specialty) &&
                                                                         pr.Practitioner.IsExactly(role.Practitioner));

            if (existingRole == null && (role.Location.Any() || role.Specialty.Any()))
            {
                Bundle?.AddResourceEntry(role);
            }

            return(practitioner);
        }
        public override FhirDateTime FromXml(XElement element)
        {
            if (element == null)
            {
                return(null);
            }

            var timeString = element.Attribute("value")?.Value;

            if (timeString == null)
            {
                var nullFlavor = element.Attribute("nullFlavor")?.Value;

                if (nullFlavor != null)
                {
                    Errors.Add(ParserError.CreateParseError(element, "has nullFlavor " + nullFlavor,
                                                            ParseErrorLevel.Warning));
                }
                else
                {
                    Errors.Add(ParserError.CreateParseError(element, "does NOT have value attribute",
                                                            ParseErrorLevel.Error));
                }

                return(null);
            }

            if (timeString.Length < 4)
            {
                Errors.Add(ParserError.CreateParseError(element, "has invalid value " + timeString,
                                                        ParseErrorLevel.Warning));
                return(null);
            }

            var sb = new StringBuilder();

            var timeZoneIndex = timeString.IndexOfAny(new[] { '-', '+' });

            if (timeZoneIndex == -1)
            {
                timeZoneIndex = timeString.Length;
            }

            for (var i = 0; i < timeZoneIndex; i++)
            {
                if (i == 4 || i == 6)
                {
                    sb.Append("-");
                }
                else if (i == 8)
                {
                    sb.Append("T");
                }
                else if (i == 10 || i == 12)
                {
                    sb.Append(":");
                }

                sb.Append(timeString[i]);
            }

            if (timeZoneIndex == 10)
            {
                sb.Append(":00:00");
            }
            else if (timeZoneIndex == 12)
            {
                sb.Append(":00");
            }

            for (var i = timeZoneIndex; i < timeString.Length; i++)
            {
                if (i == timeZoneIndex + 3)
                {
                    sb.Append(":");
                }
                sb.Append(timeString[i]);
            }

            return(new FhirDateTime {
                Value = sb.ToString()
            });


            //    var format = string.Empty;

            //var timeZoneIndex = timeString.IndexOfAny(new char[] { '-', '+' });

            //if (timeZoneIndex == -1)
            //    timeZoneIndex = timeString.Length;

            //switch (timeZoneIndex)
            //{
            //    case 4:
            //        format = "yyyy";
            //        break;
            //    case 6:
            //        format = "yyyyMM";
            //        break;
            //    case 8:
            //        format = "yyyyMMdd";
            //        break;
            //    case 10:
            //        format = "yyyyMMddHH";
            //        break;
            //    case 12:
            //        format = "yyyyMMddHHmm";
            //        break;
            //    case 14:
            //        format = "yyyyMMddHHmmss";
            //        break;
            //    case 19:
            //        format = "yyyyMMddHHmmss.ffff";
            //        break;
            //}


            //if (timeZoneIndex == timeString.Length - 3)
            //    format += "zz";
            //else if (timeZoneIndex == timeString.Length - 5)
            //{
            //    format += "zzz";
            //    timeString = timeString.Insert(timeString.Length - 2, ":");
            //}

            //DateTime datetime = DateTime.ParseExact(timeString, format, null).ToUniversalTime();

            //return new FhirDateTime(datetime);
        }
        public override RelatedPerson FromXml(XElement element)
        {
            if (element == null)
            {
                return(null);
            }

            var relatedPerson = new RelatedPerson
            {
                Id = Guid.NewGuid().ToString()
            };

            var classCode = element.Attribute("classCode")?.Value;

            if (!string.IsNullOrEmpty(classCode))
            {
                relatedPerson.Relationship = new CodeableConcept
                {
                    Coding = new List <Coding>
                    {
                        new Coding("urn:oid:2.16.840.1.113883.1.11.19563", classCode)
                    }
                }
            }
            ;

            foreach (var child in element.Elements())
            {
                switch (child.Name.LocalName)
                {
                case "code":
                    relatedPerson.Relationship = FromXml(new CodeableConceptParser(), child);
                    break;

                case "addr":
                    var addr = FromXml(new AddressParser(), child);
                    if (addr != null)
                    {
                        relatedPerson.Address.Add(addr);
                    }
                    break;

                case "telecom":
                    var contactPoint = FromXml(new ContactPointParser(), child);
                    if (contactPoint != null)
                    {
                        relatedPerson.Telecom.Add(contactPoint);
                    }
                    break;

                case "guardianPerson":
                case "relatedPerson":
                case "associatedPerson":
                    var name = FromXml(new HumanNameParser(), child.CdaElement("name"));
                    if (name != null)
                    {
                        relatedPerson.Name.Add(name);
                    }
                    break;
                }
            }

            if (!relatedPerson.Name.Any())
            {
                Errors.Add(ParserError.CreateParseError(element, "does NOT have name element",
                                                        ParseErrorLevel.Warning));
            }

            var existingPerson = Bundle?.FirstOrDefault <RelatedPerson>(p => p.Name.IsExactly(relatedPerson.Name));

            if (existingPerson != null)
            {
                return(existingPerson);
            }

            Bundle?.AddResourceEntry(relatedPerson);

            return(relatedPerson);
        }
    }
        public override Patient FromXml(XElement element)
        {
            if (element == null)
            {
                return(null);
            }

            var patient = new Patient
            {
                Id   = Guid.NewGuid().ToString(),
                Meta = new Meta
                {
                    Profile = new List <string>
                    {
                        "http://hl7.org/fhir/us/core/StructureDefinition/us-core-patient"
                    }
                }
            };

            Bundle?.AddResourceEntry(patient);

            foreach (var child in element.Elements())
            {
                if (child.Name.LocalName == "id")
                {
                    var id = FromXml(new IdentifierParser(), child);

                    if (id != null)
                    {
                        patient.Identifier.Add(id);
                    }
                }
                else if (child.Name.LocalName == "addr")
                {
                    var addr = FromXml(new AddressParser(), child);

                    if (addr != null)
                    {
                        patient.Address.Add(addr);
                    }
                }
                else if (child.Name.LocalName == "telecom")
                {
                    var contactPoint = FromXml(new ContactPointParser(), child);

                    if (contactPoint != null)
                    {
                        patient.Telecom.Add(contactPoint);
                    }
                }
                else if (child.Name.LocalName == "patient")
                {
                    ParsePatient(patient, child);
                }
                else if (child.Name.LocalName == "providerOrganization")
                {
                    var org = FromXml(new OrganizationParser(Bundle), child);
                    if (org != null && Bundle != null)
                    {
                        patient.ManagingOrganization = new ResourceReference($"{org.TypeName}/{org.Id}");
                    }
                }
            }

            if (!patient.Identifier.Any())
            {
                Errors.Add(ParserError.CreateParseError(element, "does NOT have id element", ParseErrorLevel.Error));
            }

            if (!patient.Name.Any())
            {
                Errors.Add(ParserError.CreateParseError(element, "does NOT have name element", ParseErrorLevel.Error));
            }

            if (patient.Gender == null)
            {
                Errors.Add(ParserError.CreateParseError(element, "does NOT have administrativeGenderCode element",
                                                        ParseErrorLevel.Error));
            }

            return(patient);
        }
예제 #12
0
        public override Organization FromXml(XElement element)
        {
            if (element == null)
            {
                return(null);
            }

            var org = new Organization
            {
                Id   = Guid.NewGuid().ToString(),
                Meta = new Meta
                {
                    Profile = new List <string>
                    {
                        "http://hl7.org/fhir/us/core/StructureDefinition/us-core-organization"
                    }
                },
                Active = true
            };

            foreach (var child in element.Elements())
            {
                if (child.Name.LocalName == "id")
                {
                    var id = new IdentifierParser().FromXml(child, Errors);

                    if (id != null)
                    {
                        org.Identifier.Add(id);
                    }
                }
                else if (child.Name.LocalName == "name")
                {
                    org.Name = child.Value;
                }
                else if (child.Name.LocalName == "telecom")
                {
                    var telecom = new ContactPointParser().FromXml(child, Errors);

                    if (telecom != null)
                    {
                        org.Telecom.Add(telecom);
                    }
                }
                else if (child.Name.LocalName == "addr")
                {
                    var addr = new AddressParser().FromXml(child, Errors);

                    if (addr != null)
                    {
                        org.Address.Add(addr);
                    }
                }
            }

            if (!org.Identifier.Any())
            {
                Errors.Add(ParserError.CreateParseError(element, "does NOT have id element", ParseErrorLevel.Error));
            }

            if (string.IsNullOrEmpty(org.Name))
            {
                Errors.Add(ParserError.CreateParseError(element, "does NOT have name element", ParseErrorLevel.Error));
            }

            if (!org.Telecom.Any())
            {
                Errors.Add(
                    ParserError.CreateParseError(element, "does NOT have telecom element", ParseErrorLevel.Error));
            }

            if (!org.Address.Any())
            {
                Errors.Add(ParserError.CreateParseError(element, "does NOT have addr element", ParseErrorLevel.Error));
            }

            var existingOrg = Bundle?.FirstOrDefault <Organization>(p => p.Identifier.IsExactly(org.Identifier));

            if (existingOrg == null)
            {
                Bundle?.AddResourceEntry(org);
            }
            else
            {
                org = existingOrg;
            }

            return(org);
        }