/// <summary> /// Adds examples for the profiles to the ZIP package. Only adds valid samples to the zip package. /// </summary> /// <remarks>Attempts to use the fhir-net-api to parse the resource as Xml and then as Json. If the sample /// cannot be parsed successfully, then it is skipped and not added to the ZIP package.</remarks> private void AddExamples() { // Validate that each of the samples associated with profiles has the required fields var templateExamples = (from t in this.templates join ts in this.tdb.TemplateSamples on t.Id equals ts.TemplateId select new { Template = t, Sample = ts }); foreach (var templateExample in templateExamples) { fhir_stu3.Hl7.Fhir.Model.Resource resource = null; string fileExtension = ""; try { resource = FhirParser.ParseResourceFromXml(templateExample.Sample.XmlSample); fileExtension = "xml"; } catch { } try { if (resource == null) { resource = FhirParser.ParseResourceFromJson(templateExample.Sample.XmlSample); fileExtension = "json"; } } catch { } if (resource == null || string.IsNullOrEmpty(resource.Id)) { continue; } string fileName = string.Format("resources/{0}/{1}.{2}", resource.ResourceType.ToString().ToLower(), resource.Id, fileExtension); this.zip.AddEntry(fileName, templateExample.Sample.XmlSample); } }
/// <summary> /// Adds individual FHIR Resource Instance files attached to the implementation guide being exported /// to the ZIP package /// </summary> /// <remarks>Uses the mime-type of the file to determine if the attached file is xml or json.</remarks> private void AddResourceInstances() { // Check that each FHIR resource instance is valid and has the required fields foreach (var file in ig.Files) { var fileData = file.GetLatestData(); fhir_stu3.Hl7.Fhir.Model.Resource resource = null; string fileExtension = ""; try { string fileContent = System.Text.Encoding.UTF8.GetString(fileData.Data); if (file.MimeType == "application/xml" || file.MimeType == "text/xml") { resource = FhirParser.ParseResourceFromXml(fileContent); fileExtension = "xml"; } else if (file.MimeType == "application/json") { resource = FhirParser.ParseResourceFromJson(fileContent); fileExtension = "json"; } } catch { } if (resource == null || string.IsNullOrEmpty(resource.Id)) { continue; } string fileName = string.Format("resources/{0}/{1}.{2}", resource.ResourceType.ToString().ToLower(), resource.Id, fileExtension); this.zip.AddEntry(fileName, fileData.Data); } }
public override List <ValidationResult> ValidateTemplate(Template template, SimpleSchema igSchema, IEnumerable <Template> allContainedTemplates = null) { List <ValidationResult> results = base.ValidateTemplate(template, igSchema, allContainedTemplates); var noHttpValueSets = (from tc in template.ChildConstraints join vs in this.tdb.ValueSets on tc.ValueSetId equals vs.Id where vs.Identifiers.Count(y => y.Type == ValueSetIdentifierTypes.HTTP) == 0 select new { ConstraintNumber = tc.Number, ValueSet = vs }); foreach (var noHttpValueSet in noHttpValueSets) { string vsIdentifier = noHttpValueSet.ValueSet.GetIdentifier(ValueSetIdentifierTypes.HTTP); results.Add(new ValidationResult() { ConstraintNumber = noHttpValueSet.ConstraintNumber, Level = ValidationLevels.Error, Message = string.Format("The constraint references a value set ({0}) that does not have an HTTP identifier", vsIdentifier), TemplateId = template.Id, TemplateName = template.Name }); } foreach (var templateExample in template.TemplateSamples) { fhir_stu3.Hl7.Fhir.Model.Resource resource = null; try { resource = fhirXmlParser.Parse <fhir_stu3.Hl7.Fhir.Model.Resource>(templateExample.XmlSample); } catch { } try { if (resource == null) { resource = fhirJsonParser.Parse <fhir_stu3.Hl7.Fhir.Model.Resource>(templateExample.XmlSample); } } catch { } if (resource == null) { results.Add(new ValidationResult() { TemplateId = template.Id, TemplateName = template.Name, Level = ValidationLevels.Error, Message = string.Format("Profile sample \"{0}\" cannot be parsed as a valid XML or JSON resource.", templateExample.Name) }); } else if (string.IsNullOrEmpty(resource.Id)) { results.Add(new ValidationResult() { TemplateId = template.Id, TemplateName = template.Name, Level = ValidationLevels.Error, Message = string.Format("Profile sample \"{0}\" does not have an \"id\" property.", templateExample.Name) }); } } return(results); }
protected override ValidationResults ValidateImplementationGuide(ImplementationGuide implementationGuide, SimpleSchema igSchema) { ValidationResults results = base.ValidateImplementationGuide(implementationGuide, igSchema); // Check that the implementation guide has a base identifier/url if (string.IsNullOrEmpty(implementationGuide.Identifier)) { results.Messages.Add("Implementation guide does not have a base identifier/url."); } // Check that each FHIR resource instance is valid and has the required fields foreach (var file in implementationGuide.Files) { var fileData = file.GetLatestData(); fhir_stu3.Hl7.Fhir.Model.Resource resource = null; string fileContent = System.Text.Encoding.UTF8.GetString(fileData.Data); try { resource = this.fhirXmlParser.Parse <fhir_stu3.Hl7.Fhir.Model.Resource>(fileContent); } catch (Exception ex) { if (file.MimeType == "application/xml" || file.MimeType == "text/xml") { results.Messages.Add("FHIR Resource instance \"" + file.FileName + "\" cannot be parsed as valid XML: " + ex.Message); } } try { if (resource == null) { resource = this.fhirJsonParser.Parse <fhir_stu3.Hl7.Fhir.Model.Resource>(fileContent); } } catch (Exception ex) { if (file.MimeType == "binary/octet-stream" || file.MimeType == "application/json") { results.Messages.Add("FHIR Resource instance \"" + file.FileName + "\" cannot be parsed as valid JSON: " + ex.Message); } } if (resource != null && string.IsNullOrEmpty(resource.Id)) { string msg = string.Format("FHIR resource instance \"" + file.FileName + "\" does not have an \"id\" property."); results.Messages.Add(msg); } } List <string> resourceIds = new List <string>(); // Go through each of the FHIR Resource Instance files associated with the implementation guide and get the resource type and id for each one foreach (var file in implementationGuide.Files.Where(y => y.ContentType == ImplementationGuideFile.ContentTypeFHIRResourceInstance)) { fhir_stu3.Hl7.Fhir.Model.Resource resource = null; string fileContent = Encoding.UTF8.GetString(file.GetLatestData().Data); try { if (file.MimeType.Contains("json")) { fhir_stu3.Hl7.Fhir.Serialization.FhirJsonParser parser = new FhirJsonParser(); resource = parser.Parse <fhir_stu3.Hl7.Fhir.Model.Resource>(fileContent); } else if (file.MimeType.Contains("xml")) { fhir_stu3.Hl7.Fhir.Serialization.FhirXmlParser parser = new FhirXmlParser(); resource = parser.Parse <fhir_stu3.Hl7.Fhir.Model.Resource>(fileContent); } } catch { // Do nothing? Skip? } if (resource != null) { // Ex: Questionnaire/ssi-questionnaire resourceIds.Add(resource.ResourceType + "/" + resource.Id); } } // Go through each of the profile samples, and do the same thing. Loop through each template in the IG, and Template.TemplateSamples var allTemplateSamples = implementationGuide.ChildTemplates.SelectMany(y => y.TemplateSamples); foreach (var templateSample in allTemplateSamples) { fhir_stu3.Hl7.Fhir.Model.Resource resource = null; string fileContent = templateSample.XmlSample; try { fhir_stu3.Hl7.Fhir.Serialization.FhirXmlParser parser = new FhirXmlParser(); resource = parser.Parse <fhir_stu3.Hl7.Fhir.Model.Resource>(fileContent); } catch { // Do nothing } if (resource != null) { resourceIds.Add(resource.ResourceType + "/" + resource.Id); } } // Go through each of the profiles and determine their StructureDefinition/<id> as well, add to list foreach (var template in implementationGuide.ChildTemplates) { String resourceId = template.Oid.Substring(template.Oid.IndexOf("StructureDefinition/") + 20); resourceIds.Add(template.PrimaryContextType + "/" + resourceId); } // Check the list of resourceIds for duplicates (suggest using some form of linq query - search online) var duplicateCheck = resourceIds.GroupBy(x => x) .Where(g => g.Count() > 1) .Select(d => d.Key).ToList(); // For each duplicate, create a resources.Messages error. Flag results.RestrictDownload if any duplicates, cause the exports will error out. if (duplicateCheck.Count != 0) { results.RestrictDownload = true; foreach (var duplicate in duplicateCheck) { results.Messages.Add("Export Restricted: Entry with type and id " + duplicate.ToString() + " appears more than once within this implementation guide as an IG sample file, as a sample associated with a profile within the IG, or a profile"); } } return(results); }
public IEnumerable <string> ValidateXml(XMLSettingsModel model) { List <string> messages = new List <string>(); ImplementationGuide ig = this.tdb.ImplementationGuides.SingleOrDefault(y => y.Id == model.ImplementationGuideId); var templates = (from t in this.tdb.Templates join tid in model.TemplateIds on t.Id equals tid select t); if (ig == null) { messages.Add("Could not find implementation guide with id " + model.ImplementationGuideId); return(messages); } switch (model.XmlType) { case XMLSettingsModel.ExportTypes.FHIRBuild: // Check that the implementation guide has a base identifier/url if (string.IsNullOrEmpty(ig.Identifier)) { messages.Add("Implementation guide does not have a base identifier/url."); } // Check that each FHIR resource instance is valid and has the required fields foreach (var file in ig.Files) { var fileData = file.GetLatestData(); fhir_stu3.Hl7.Fhir.Model.Resource resource = null; try { string fileContent = System.Text.Encoding.UTF8.GetString(fileData.Data); if (file.MimeType == "application/xml" || file.MimeType == "text/xml") { resource = fhir_stu3.Hl7.Fhir.Serialization.FhirParser.ParseResourceFromXml(fileContent); } else if (file.MimeType == "application/json") { resource = fhir_stu3.Hl7.Fhir.Serialization.FhirParser.ParseResourceFromJson(fileContent); } } catch { } if (resource == null) { string msg = string.Format("FHIR resource instance \"" + file.FileName + "\" cannot be parsed as a valid XML or JSON resource."); messages.Add(msg); } if (string.IsNullOrEmpty(resource.Id)) { string msg = string.Format("FHIR resource instance \"" + file.FileName + "\" does not have an \"id\" property."); messages.Add(msg); } } // Validate that each of the samples associated with profiles has the required fields var templateExamples = (from t in templates join ts in this.tdb.TemplateSamples on t.Id equals ts.TemplateId select new { Template = t, Sample = ts }); foreach (var templateExample in templateExamples) { fhir_stu3.Hl7.Fhir.Model.Resource resource = null; try { resource = fhir_stu3.Hl7.Fhir.Serialization.FhirParser.ParseResourceFromXml(templateExample.Sample.XmlSample); } catch { } try { if (resource == null) { resource = fhir_stu3.Hl7.Fhir.Serialization.FhirParser.ParseResourceFromJson(templateExample.Sample.XmlSample); } } catch { } if (resource == null) { string msg = string.Format("Profile sample \"" + templateExample.Sample.Name + "\" cannot be parsed as a valid XML or JSON resource."); messages.Add(msg); } else if (string.IsNullOrEmpty(resource.Id)) { string msg = string.Format("Profile sample \"" + templateExample.Sample.Name + "\" does not have an \"id\" property."); messages.Add(msg); } } break; } return(messages); }