diff --git a/firely-validator-api-tests.props b/firely-validator-api-tests.props
index 5de794fb..406be249 100644
--- a/firely-validator-api-tests.props
+++ b/firely-validator-api-tests.props
@@ -8,7 +8,7 @@
- 5.7.0
+ 5.8.1
diff --git a/firely-validator-api.props b/firely-validator-api.props
index 94046397..35de9701 100644
--- a/firely-validator-api.props
+++ b/firely-validator-api.props
@@ -27,7 +27,7 @@
- 5.7.0
+ 5.8.1
diff --git a/src/Firely.Fhir.Validation.Shared/Validator.cs b/src/Firely.Fhir.Validation.Shared/Validator.cs
index 59459a09..090dbc26 100644
--- a/src/Firely.Fhir.Validation.Shared/Validator.cs
+++ b/src/Firely.Fhir.Validation.Shared/Validator.cs
@@ -82,6 +82,9 @@ public Validator(
internal OperationOutcome Validate(IScopedNode sn, string? profile = null)
{
+ if (sn.InstanceType is null)
+ throw new ArgumentException($"Cannot validate the resource because {nameof(IScopedNode)} does not have an instance type.");
+
profile ??= Canonical.ForCoreType(sn.InstanceType).ToString();
#pragma warning disable CS0618 // Type or member is obsolete
diff --git a/src/Firely.Fhir.Validation/Impl/CanonicalValidator.cs b/src/Firely.Fhir.Validation/Impl/CanonicalValidator.cs
index 5c07547a..efbdc009 100644
--- a/src/Firely.Fhir.Validation/Impl/CanonicalValidator.cs
+++ b/src/Firely.Fhir.Validation/Impl/CanonicalValidator.cs
@@ -45,7 +45,7 @@ ResultReport IValidatable.Validate(IScopedNode input, ValidationSettings vc, Val
}
default:
return new IssueAssertion(Issue.CONTENT_ELEMENT_INVALID_PRIMITIVE_VALUE,
- $"Primitive does not have the correct type ({input.Value.GetType()})").AsResult(state);
+ $"Primitive does not have the correct type ({input.Value?.GetType()})").AsResult(state);
}
}
}
diff --git a/src/Firely.Fhir.Validation/Impl/ChildrenValidator.cs b/src/Firely.Fhir.Validation/Impl/ChildrenValidator.cs
index 603d0899..d9196731 100644
--- a/src/Firely.Fhir.Validation/Impl/ChildrenValidator.cs
+++ b/src/Firely.Fhir.Validation/Impl/ChildrenValidator.cs
@@ -9,6 +9,7 @@
using Hl7.Fhir.Support;
using Hl7.Fhir.Utility;
using Newtonsoft.Json.Linq;
+using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
@@ -87,6 +88,9 @@ public JToken ToJson() =>
///
ResultReport IValidatable.Validate(IScopedNode input, ValidationSettings vc, ValidationState state)
{
+ if (input.InstanceType is null)
+ throw new ArgumentException($"Cannot validate the resource because {nameof(IScopedNode)} does not have an instance type.");
+
var evidence = new List();
// Listing children can be an expensive operation, so make sure we run it once.
diff --git a/src/Firely.Fhir.Validation/Impl/DatatypeSchema.cs b/src/Firely.Fhir.Validation/Impl/DatatypeSchema.cs
index c38e9b49..c38bdef0 100644
--- a/src/Firely.Fhir.Validation/Impl/DatatypeSchema.cs
+++ b/src/Firely.Fhir.Validation/Impl/DatatypeSchema.cs
@@ -55,6 +55,11 @@ internal override ResultReport ValidateInternal(IScopedNode input, ValidationSet
if (vc.ElementSchemaResolver is null)
throw new ArgumentException($"Cannot validate the resource because {nameof(ValidationSettings)} does not contain an ElementSchemaResolver.");
+ if (input.InstanceType is null)
+ {
+ throw new ArgumentException($"Cannot validate the resource because {nameof(IScopedNode)} does not have an instance type.");
+ }
+
var typeProfile = vc.TypeNameMapper.MapTypeName(input.InstanceType);
var fetchResult = FhirSchemaGroupAnalyzer.FetchSchema(vc.ElementSchemaResolver, state, typeProfile);
return fetchResult.Success ? fetchResult.Schema!.ValidateInternal(input, vc, state) : fetchResult.Error!;
diff --git a/src/Firely.Fhir.Validation/Impl/FhirSchema.cs b/src/Firely.Fhir.Validation/Impl/FhirSchema.cs
index 8f8813f4..9feff8e3 100644
--- a/src/Firely.Fhir.Validation/Impl/FhirSchema.cs
+++ b/src/Firely.Fhir.Validation/Impl/FhirSchema.cs
@@ -7,6 +7,7 @@
*/
using Newtonsoft.Json.Linq;
+using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
@@ -51,6 +52,9 @@ public FhirSchema(StructureDefinitionInformation structureDefinition, IEnumerabl
///
internal override ResultReport ValidateInternal(IScopedNode input, ValidationSettings vc, ValidationState state)
{
+ if (input.InstanceType is null)
+ throw new ArgumentException($"Cannot validate the resource because {nameof(IScopedNode)} does not have an instance type.");
+
state = state
.UpdateLocation(sp => sp.InvokeSchema(this))
.UpdateInstanceLocation(ip => ip.StartResource(input.InstanceType));
diff --git a/src/Firely.Fhir.Validation/Impl/FhirStringValidator.cs b/src/Firely.Fhir.Validation/Impl/FhirStringValidator.cs
index 2d817859..81f9c923 100644
--- a/src/Firely.Fhir.Validation/Impl/FhirStringValidator.cs
+++ b/src/Firely.Fhir.Validation/Impl/FhirStringValidator.cs
@@ -36,7 +36,7 @@ ResultReport IValidatable.Validate(IScopedNode input, ValidationSettings vc, Val
}
default:
return new IssueAssertion(Issue.CONTENT_ELEMENT_INVALID_PRIMITIVE_VALUE,
- $"Primitive does not have the correct type ({input.Value.GetType()})").AsResult(state);
+ $"Primitive does not have the correct type ({input.Value?.GetType()})").AsResult(state);
}
}
}
diff --git a/src/Firely.Fhir.Validation/Impl/FhirTxt2Validator.cs b/src/Firely.Fhir.Validation/Impl/FhirTxt2Validator.cs
index ff03c5f4..c176abe5 100644
--- a/src/Firely.Fhir.Validation/Impl/FhirTxt2Validator.cs
+++ b/src/Firely.Fhir.Validation/Impl/FhirTxt2Validator.cs
@@ -41,7 +41,7 @@ public class FhirTxt2Validator : InvariantValidator
internal override (bool, ResultReport?) RunInvariant(IScopedNode input, ValidationSettings vc, ValidationState _)
{
//Check whether the narrative contains non-whitespace content.
- return (!string.IsNullOrWhiteSpace(input.Value.ToString()), null);
+ return (!string.IsNullOrWhiteSpace(input.Value?.ToString()), null);
}
///
diff --git a/src/Firely.Fhir.Validation/Impl/FixedValidator.cs b/src/Firely.Fhir.Validation/Impl/FixedValidator.cs
index 05085f37..96d0d88f 100644
--- a/src/Firely.Fhir.Validation/Impl/FixedValidator.cs
+++ b/src/Firely.Fhir.Validation/Impl/FixedValidator.cs
@@ -56,7 +56,7 @@ ResultReport IValidatable.Validate(IScopedNode input, ValidationSettings _, Vali
return ResultReport.SUCCESS;
static string displayValue(ITypedElement te) =>
- te.Children().Any() ? te.ToJson() : te.Value.ToString()!;
+ te.Children().Any() ? te.ToJson() : te.Value!.ToString()!;
}
///
diff --git a/src/Firely.Fhir.Validation/Impl/PatternValidator.cs b/src/Firely.Fhir.Validation/Impl/PatternValidator.cs
index af1e3e8f..87ec9a96 100644
--- a/src/Firely.Fhir.Validation/Impl/PatternValidator.cs
+++ b/src/Firely.Fhir.Validation/Impl/PatternValidator.cs
@@ -58,7 +58,7 @@ ResultReport IValidatable.Validate(IScopedNode input, ValidationSettings _, Vali
return result;
static string displayValue(ITypedElement te) =>
- te.Children().Any() ? te.ToJson() : te.Value.ToString()!;
+ te.Children().Any() ? te.ToJson() : te.Value!.ToString()!;
}
///
diff --git a/src/Firely.Fhir.Validation/Impl/ReferencedInstanceValidator.cs b/src/Firely.Fhir.Validation/Impl/ReferencedInstanceValidator.cs
index bce90b96..4304bc45 100644
--- a/src/Firely.Fhir.Validation/Impl/ReferencedInstanceValidator.cs
+++ b/src/Firely.Fhir.Validation/Impl/ReferencedInstanceValidator.cs
@@ -73,6 +73,9 @@ ResultReport IValidatable.Validate(IScopedNode input, ValidationSettings vc, Val
if (vc.ElementSchemaResolver is null)
throw new ArgumentException($"Cannot validate because {nameof(ValidationSettings)} does not contain an ElementSchemaResolver.");
+ if (input.InstanceType is null)
+ throw new ArgumentException($"Cannot validate the resource because {nameof(IScopedNode)} does not have an instance type.");
+
if (!IsSupportedReferenceType(input.InstanceType))
return new IssueAssertion(Issue.CONTENT_REFERENCE_OF_INVALID_KIND,
$"Expected a reference type here (reference or canonical) not a {input.InstanceType}.")
@@ -127,7 +130,7 @@ private record ResolutionResult(ITypedElement? ReferencedResource, AggregationMo
// First, try to resolve within this instance (in contained, Bundle.entry)
resolveLocally(input.ToScopedNode(), reference, s, out var resolution)
];
-
+
// Now that we have tried to fetch the reference locally, we have also determined the kind of
// reference we are dealing with, so check it for aggregation and versioning rules.
if (HasAggregation && AggregationRules?.Any(a => a == resolution.ReferenceKind) == false)
@@ -258,9 +261,9 @@ public JToken ToJson()
///
/// Whether this validator supports validating a given reference type.
///
- internal static bool IsSupportedReferenceType(string typeCode) =>
+ internal static bool IsSupportedReferenceType(string typeCode) =>
IsReferenceType(typeCode) && typeCode is not "canonical";
-
+
///
/// Whether a type is a reference type.
///
diff --git a/src/Firely.Fhir.Validation/Impl/ResourceSchema.cs b/src/Firely.Fhir.Validation/Impl/ResourceSchema.cs
index 7a4964d1..c695210b 100644
--- a/src/Firely.Fhir.Validation/Impl/ResourceSchema.cs
+++ b/src/Firely.Fhir.Validation/Impl/ResourceSchema.cs
@@ -74,6 +74,9 @@ internal override ResultReport ValidateInternal(IEnumerable input,
///
internal override ResultReport ValidateInternal(IScopedNode input, ValidationSettings vc, ValidationState state)
{
+ if (input.InstanceType is null)
+ throw new ArgumentException($"Cannot validate the resource because {nameof(IScopedNode)} does not have an instance type.");
+
// FHIR specific rule about dealing with abstract datatypes (not profiles!): if this schema is an abstract datatype,
// we need to run validation against the schema for the actual type, not the abstract type.
if (StructureDefinition.IsAbstract && StructureDefinition.Derivation != StructureDefinitionInformation.TypeDerivationRule.Constraint)
diff --git a/src/Firely.Fhir.Validation/Schema/ValueElementNode.cs b/src/Firely.Fhir.Validation/Schema/ValueElementNode.cs
index 2a49c1e5..e0c2428a 100644
--- a/src/Firely.Fhir.Validation/Schema/ValueElementNode.cs
+++ b/src/Firely.Fhir.Validation/Schema/ValueElementNode.cs
@@ -23,9 +23,9 @@ public ValueElementNode(IScopedNode wrapped)
public string Name => "value";
- public string InstanceType => TypeSpecifier.ForNativeType(_wrapped.Value.GetType()).FullName;
+ public string? InstanceType => (_wrapped.Value is not null) ? TypeSpecifier.ForNativeType(_wrapped.Value.GetType()).FullName : null;
- public object Value => _wrapped.Value;
+ public object? Value => _wrapped.Value;
public IEnumerable Children(string? name = null) => Enumerable.Empty();
}
diff --git a/src/Firely.Fhir.Validation/Support/ScopedNodeToTypedElementAdapter.cs b/src/Firely.Fhir.Validation/Support/ScopedNodeToTypedElementAdapter.cs
index a33d9314..8c80f4a1 100644
--- a/src/Firely.Fhir.Validation/Support/ScopedNodeToTypedElementAdapter.cs
+++ b/src/Firely.Fhir.Validation/Support/ScopedNodeToTypedElementAdapter.cs
@@ -36,9 +36,9 @@ public ScopedNodeToTypedElementAdapter(IScopedNode adaptee)
public string Name => _adaptee.Name;
- public string InstanceType => _adaptee.InstanceType;
+ public string? InstanceType => _adaptee.InstanceType;
- public object Value => _adaptee.Value;
+ public object? Value => _adaptee.Value;
public IEnumerable Children(string? name = null) =>
_adaptee.Children(name).Select(n => new ScopedNodeToTypedElementAdapter(n));
diff --git a/src/Firely.Fhir.Validation/Support/TypedElementToIScopedNodeToAdapter.cs b/src/Firely.Fhir.Validation/Support/TypedElementToIScopedNodeToAdapter.cs
index 28294ab8..40d6e207 100644
--- a/src/Firely.Fhir.Validation/Support/TypedElementToIScopedNodeToAdapter.cs
+++ b/src/Firely.Fhir.Validation/Support/TypedElementToIScopedNodeToAdapter.cs
@@ -29,9 +29,9 @@ private TypedElementToIScopedNodeToAdapter(ITypedElement adaptee)
public string Name => _adaptee.Name;
- public string InstanceType => _adaptee.InstanceType;
+ public string? InstanceType => _adaptee.InstanceType;
- public object Value => _adaptee.Value;
+ public object? Value => _adaptee.Value;
IEnumerable IBaseElementNavigator.Children(string? name) =>
_adaptee.Children(name).Select(n => new TypedElementToIScopedNodeToAdapter(n));
diff --git a/test/Firely.Fhir.Validation.Compilation.Tests.Shared/FhirTests/DotNetValidator.cs b/test/Firely.Fhir.Validation.Compilation.Tests.Shared/FhirTests/DotNetValidator.cs
index f6f3b404..86a7c814 100644
--- a/test/Firely.Fhir.Validation.Compilation.Tests.Shared/FhirTests/DotNetValidator.cs
+++ b/test/Firely.Fhir.Validation.Compilation.Tests.Shared/FhirTests/DotNetValidator.cs
@@ -137,7 +137,7 @@ IEnumerable getProfiles(ITypedElement node, string? profile = null)
yield return profile;
}
- var instanceType = ModelInfo.CanonicalUriForFhirCoreType(node.InstanceType);
+ var instanceType = node.InstanceType is not null ? ModelInfo.CanonicalUriForFhirCoreType(node.InstanceType) : null;
if (instanceType is not null)
{
yield return instanceType!;
diff --git a/test/Firely.Fhir.Validation.Tests/Support/ElementNodeAdapter.cs b/test/Firely.Fhir.Validation.Tests/Support/ElementNodeAdapter.cs
index a0d7f8bc..134cd216 100644
--- a/test/Firely.Fhir.Validation.Tests/Support/ElementNodeAdapter.cs
+++ b/test/Firely.Fhir.Validation.Tests/Support/ElementNodeAdapter.cs
@@ -20,13 +20,13 @@ internal class ElementNodeAdapter : ITypedElement
public string Name => _elementNodeInstance.Name;
- public string InstanceType => _elementNodeInstance.InstanceType;
+ public string InstanceType => _elementNodeInstance.InstanceType!;
- public object Value => _elementNodeInstance.Value;
+ public object Value => _elementNodeInstance.Value!;
public string Location => _elementNodeInstance.Location;
- public IElementDefinitionSummary Definition => _elementNodeInstance.Definition;
+ public IElementDefinitionSummary Definition => _elementNodeInstance.Definition!;
public static ElementNodeAdapter Root(string type, string? name = null, object? value = null)
{
diff --git a/test/Firely.Fhir.Validation.Tests/Support/TypedElementOnDictionary.cs b/test/Firely.Fhir.Validation.Tests/Support/TypedElementOnDictionary.cs
index 2b9421bd..2075ab36 100644
--- a/test/Firely.Fhir.Validation.Tests/Support/TypedElementOnDictionary.cs
+++ b/test/Firely.Fhir.Validation.Tests/Support/TypedElementOnDictionary.cs
@@ -45,7 +45,7 @@ private static ITypedElement forObject(string name, object value, string locatio
else
{
_ = ElementNode.TryConvertToElementValue(value, out var primitive);
- return new ConstantElement(name, ts.FullName, primitive, location);
+ return new ConstantElement(name, ts.FullName, primitive!, location);
}
}
}
@@ -102,7 +102,7 @@ public IEnumerable Children(string? name) =>
Enumerable.Empty();
}
- public IEnumerable