Repository: FHIR/sushi
Pull request #1240 (2023-03-20 20:56:49)

Improve import & export of ids/extensions on primitives
In FHIR JSON, ids and extensions on primitives are represented by creating a shadow property prefixed with an underscore. For example, to set an extension on `StructureDefinition.baseDefinition`, you assign and object containing `extension` to `StructureDefinition._baseDefinition`.  For more information see [JSON representation of primitive elements](https://hl7.org/fhir/json.html#primitive).

While SUSHI partially supported setting ids and extensions on primitive elements using FSH assignment rules, it _dropped_ all properties starting with `_` when it imported an SD using `StructureDefinition.fromJSON(...)`. It also did not propertly consider `_` properties when calculating differentials.

This PR adds support for importing `_` properties in `StructureDefinition.fromJSON` and improves support for exporting `_` properties via `StructureDefinition.toJSON` and detecting differentials. Once these improvements were made, however, additional adjustments were required:
* When `ElementDefinition.type.profile` or `ElementDefinition.type.targetProfile` arrays are manipulated, the shadow `_profile` and `_targetProfile` arrays must also be adjusted to maintain the relationship between indices. In addition, when a profile or targetProfile is changed, the original extensions may no longer apply, so they are removed.
* When a SD is used as a parent and that SD has `_`-prefixed properties, we strip the `_`-prefixed properties because in many (or most) cases, they don't necessarily apply to the child SD.

I've split up commits by broken tests and fixes if you'd like to go through the wild ride one commit at a time.

I've also run a full regression. It affects two IGs: `HL7/fhir-mCODE-ig#master` and `HL7/fhir-pacio-pfe#master`. In both cases, must-support extensions are target profiles are now (properly) inherited from their US Core parents.


Patch:
diff --git a/src/export/StructureDefinitionExporter.ts b/src/export/StructureDefinitionExporter.ts
index fd15192..8733f04 100644
--- a/src/export/StructureDefinitionExporter.ts
+++ b/src/export/StructureDefinitionExporter.ts
@@ -395,6 +395,15 @@ export class StructureDefinitionExporter implements Fishable {
       delete structDef.context;
       delete structDef.contextInvariant;
     }
+
+    // Remove all top-level properties that start with _, as the top-level primitive
+    // extensions on the parent may not be valid for the child.
+    Object.keys(structDef).forEach(key => {
+      if (key.startsWith('_')) {
+        // @ts-ignore
+        delete structDef[key];
+      }
+    });
   }
 
   /**
diff --git a/src/fhirtypes/ElementDefinition.ts b/src/fhirtypes/ElementDefinition.ts
index a4442cd..83899e5 100644
--- a/src/fhirtypes/ElementDefinition.ts
+++ b/src/fhirtypes/ElementDefinition.ts
@@ -12,7 +12,7 @@ import {
 import { minify } from 'html-minifier-terser';
 import { isUri } from 'valid-url';
 import { StructureDefinition } from './StructureDefinition';
-import { CodeableConcept, Coding, Quantity, Ratio, Reference } from './dataTypes';
+import { CodeableConcept, Coding, Element, Quantity, Ratio, Reference } from './dataTypes';
 import { FshCanonical, FshCode, FshRatio, FshQuantity, FshReference, Invariant } from '../fshtypes';
 import { AddElementRule, AssignmentValueType, OnlyRule } from '../fshtypes/rules';
 import {
@@ -60,15 +60,20 @@ const PROFILE_ELEMENT_EXTENSION =
   'http://hl7.org/fhir/StructureDefinition/elementdefinition-profile-element';
 
 export class ElementDefinitionType {
-  private _code: string;
+  private _actualCode: string;
+  _code?: Element;
   profile?: string[];
+  _profile?: Element[];
   targetProfile?: string[];
+  _targetProfile?: Element[];
   aggregation?: string[];
+  _aggregation?: Element[];
   versioning?: string;
+  _versioning?: Element;
   extension?: ElementDefinitionExtension[];
 
   constructor(code: string) {
-    this._code = code;
+    this._actualCode = code;
   }
 
   /**
@@ -81,15 +86,15 @@ export class ElementDefinitionType {
       ext => ext.url === 'http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type'
     );
     // R4 uses valueUrl; R5 uses valueUri
-    return fhirTypeExtension?.valueUrl ?? fhirTypeExtension?.valueUri ?? this._code;
+    return fhirTypeExtension?.valueUrl ?? fhirTypeExtension?.valueUri ?? this._actualCode;
   }
 
   set code(c: string) {
-    this._code = c;
+    this._actualCode = c;
   }
 
   getActualCode(): string {
-    return this._code;
+    return this._actualCode;
   }
 
   withProfiles(...profiles: string[]): this {
@@ -105,7 +110,7 @@ export class ElementDefinitionType {
   toJSON(): ElementDefinitionTypeJSON {
     // Remove the _code key specific to ElementDefinitionType
     const elDefTypeClone = cloneDeep(this);
-    delete elDefTypeClone._code;
+    delete elDefTypeClone._actualCode;
 
     // Create ElementDefinitionTypeJSON with a code and any properties present on the ElementDefinitionType
     const elDefTypeJSON: ElementDefinitionTypeJSON = {
@@ -120,10 +125,25 @@ export class ElementDefinitionType {
 
     // TODO: other fromJSON methods check properties for undefined.
     // investigate the implications of this change on materializing implied extensions.
+    if (json._code) {
+      elDefType._code = json._code;
+    }
     elDefType.profile = json.profile;
+    if (json._profile) {
+      elDefType._profile = json._profile;
+    }
     elDefType.targetProfile = json.targetProfile;
+    if (json._targetProfile) {
+      elDefType._targetProfile = json._targetProfile;
+    }
     elDefType.aggregation = json.aggregation;
+    if (json._aggregation) {
+      elDefType._aggregation = json._aggregation;
+    }
     elDefType.versioning = json.versioning;
+    if (json._versioning) {
+      elDefType._versioning = json._versioning;
+    }
     elDefType.extension = json.extension;
 
     return elDefType;
@@ -137,7 +157,7 @@ export class ElementDefinitionType {
  * @see {@link http://hl7.org/fhir/R4/elementdefinition.html}
  */
 export class ElementDefinition {
-  private _id: string;
+  private _privateId: string;
   path: string;
   extension: any[];
   modifierExtension: any[];
@@ -249,7 +269,7 @@ export class ElementDefinition {
   }
 
   get id(): string {
-    return this._id;
+    return this._privateId;
   }
 
   /**
@@ -258,9 +278,9 @@ export class ElementDefinition {
    * @param {string} id - the ElementDefinition id
    */
   set id(id: string) {
-    this._id = id;
+    this._privateId = id;
     // After setting the id, we should re-set the path, which is based on the id
-    this.path = this._id
+    this.path = this._privateId
       .split('.')
       .map(s => {
         // Usually the path part is just the name without the slice.
@@ -409,7 +429,7 @@ export class ElementDefinition {
   hasDiff(): boolean {
     const original = this._original ? this._original : new ElementDefinition();
     return (
-      PROPS.some(prop => {
+      PROPS_AND_UNDERPROPS.some(prop => {
         if (prop.endsWith('[x]')) {
           const re = new RegExp(`^${prop.slice(0, -3)}[A-Z].*$`);
           prop = Object.keys(this).find(p => re.test(p));
@@ -436,7 +456,7 @@ export class ElementDefinition {
     const original = this._original ? this._original : new ElementDefinition();
     const diff = new ElementDefinition(this.id);
     diff.structDef = this.structDef;
-    for (let prop of PROPS) {
+    for (let prop of PROPS_AND_UNDERPROPS) {
       if (prop.endsWith('[x]')) {
         const re = new RegExp(`^${prop.slice(0, -3)}[A-Z].*$`);
         prop = Object.keys(this).find(p => re.test(p));
@@ -945,6 +965,36 @@ export class ElementDefinition {
       newTypes.push(...this.applyTypeIntersection(type, targetType, matches));
     }
 
+    // Loop through the new types and for each one, update any _profile and _targetProfile arrays
+    // that need it. In short, if a single profile or targetProfile is unchanged, preserve its
+    // corresponding _profile or _targetProfile entry. If a profile or targetProfile is changed,
+    // and there is a _profile or _targetProfile array, make the corresponding entry null. If a
+    // _profile or _targetProfile is added, and there is a _profile or _targetProfile array, add
+    // a null entry for it.
+    for (const newType of newTypes) {
+      const originalType = this.type.find(t => t.code === newType.code);
+      delete newType._profile;
+      if (originalType && originalType._profile?.length) {
+        newType._profile = newType.profile.map(newProfile => {
+          return originalType._profile[originalType.profile.indexOf(newProfile)] ?? null;
+        });
+        if (newType._profile.length === 0 || newType._profile.every(e => e == null)) {
+          delete newType._profile;
+        }
+      }
+      delete newType._targetProfile;
+      if (originalType && originalType._targetProfile?.length) {
+        newType._targetProfile = newType.targetProfile.map(newProfile => {
+          return (
+            originalType._targetProfile[originalType.targetProfile.indexOf(newProfile)] ?? null
+          );
+        });
+        if (newType._targetProfile.length === 0 || newType._targetProfile.every(e => e == null)) {
+          delete newType._targetProfile;
+        }
+      }
+    }
+
     // Let user know if other rules have been made obsolete
     const obsoleteChoices = this.structDef.findObsoleteChoices(this, oldTypes);
     if (obsoleteChoices.length > 0) {
@@ -2593,7 +2643,7 @@ export class ElementDefinition {
    */
   toJSON(): LooseElementDefJSON {
     const j: LooseElementDefJSON = {};
-    for (let prop of PROPS) {
+    for (let prop of PROPS_AND_UNDERPROPS) {
       if (prop.endsWith('[x]')) {
         const re = new RegExp(`^${prop.slice(0, -3)}[A-Z].*$`);
         prop = Object.keys(this).find(p => re.test(p));
@@ -2621,7 +2671,7 @@ export class ElementDefinition {
    */
   static fromJSON(json: LooseElementDefJSON, captureOriginal = true): ElementDefinition {
     const ed = new ElementDefinition();
-    for (let prop of PROPS) {
+    for (let prop of PROPS_AND_UNDERPROPS) {
       if (prop.endsWith('[x]')) {
         const re = new RegExp(`^${prop.slice(0, -3)}[A-Z].*$`);
         prop = Object.keys(json).find(p => re.test(p));
@@ -2777,6 +2827,11 @@ const PROPS = [
   'mapping'
 ];
 
+const PROPS_AND_UNDERPROPS: string[] = PROPS.reduce((collect: string[], prop) => {
+  collect.push(prop, `_${prop}`);
+  return collect;
+}, []);
+
 /**
  * These list properties are considered to be additive in the differential.
  * Thus, the differential should contain only new entries in these lists.
diff --git a/src/fhirtypes/StructureDefinition.ts b/src/fhirtypes/StructureDefinition.ts
index faadf86..d84661d 100644
--- a/src/fhirtypes/StructureDefinition.ts
+++ b/src/fhirtypes/StructureDefinition.ts
@@ -400,18 +400,12 @@ export class StructureDefinition {
   toJSON(snapshot = true): any {
     const j: LooseStructDefJSON = { resourceType: this.resourceType };
     // First handle properties that are just straight translations to JSON
-    for (const prop of PROPS) {
+    for (const prop of PROPS_AND_UNDERPROPS) {
       // @ts-ignore
       if (this[prop] !== undefined) {
         // @ts-ignore
         j[prop] = cloneDeep(this[prop]);
       }
-      // children of primitive properties are located by an underscore-prefixed property name
-      // @ts-ignore
-      if (this[`_${prop}`] !== undefined) {
-        // @ts-ignore
-        j[`_${prop}`] = cloneDeep(this[`_${prop}`]);
-      }
     }
 
     // Now handle snapshot and differential
@@ -461,7 +455,7 @@ export class StructureDefinition {
   static fromJSON(json: LooseStructDefJSON, captureOriginalElements = true): StructureDefinition {
     const sd = new StructureDefinition();
     // First handle properties that are just straight translations from JSON
-    for (const prop of PROPS) {
+    for (const prop of PROPS_AND_UNDERPROPS) {
       // @ts-ignore
       if (json[prop] !== undefined) {
         // @ts-ignore
@@ -967,3 +961,8 @@ const PROPS = [
   'baseDefinition',
   'derivation'
 ];
+
+const PROPS_AND_UNDERPROPS: string[] = PROPS.reduce((collect: string[], prop) => {
+  collect.push(prop, `_${prop}`);
+  return collect;
+}, []);


Test patch:
diff --git a/test/export/StructureDefinitionExporter.test.ts b/test/export/StructureDefinitionExporter.test.ts
index 1424a7d..851005e 100644
--- a/test/export/StructureDefinitionExporter.test.ts
+++ b/test/export/StructureDefinitionExporter.test.ts
@@ -820,6 +820,31 @@ describe('StructureDefinitionExporter R4', () => {
       expect(exported.derivation).toBe('constraint'); // always constraint
     });
 
+    it('should remove inherited top-level underscore-prefixed metadata properties for a profile', () => {
+      const jsonModifiedObservation = defs.fishForFHIR('Observation');
+      jsonModifiedObservation.id = 'ModifiedObservation';
+      jsonModifiedObservation.name = 'ModifiedObservation';
+      jsonModifiedObservation.url = 'http://example.org/sd/ModifiedObservation';
+      jsonModifiedObservation._baseDefinition = {
+        extension: [
+          {
+            url: 'http://hl7.org/fhir/StructureDefinition/structuredefinition-codegen-super',
+            valueString: 'MetadataResource'
+          }
+        ]
+      };
+      pkg.resources.push(StructureDefinition.fromJSON(jsonModifiedObservation));
+
+      const profile = new Profile('Foo');
+      profile.parent = 'ModifiedObservation';
+      doc.profiles.set(profile.name, profile);
+      exporter.exportStructDef(profile);
+      const exported = pkg.profiles[0];
+      expect(exported.baseDefinition).toBe('http://example.org/sd/ModifiedObservation'); // url for ModifiedObservation
+      // @ts-ignore
+      expect(exported._baseDefinition).toBeUndefined(); // should be stripped out
+    });
+
     it('should only inherit inheritable extensions for a profile', () => {
       const parent = new Profile('FooParent');
       parent.parent = 'Observation';
@@ -1205,6 +1230,34 @@ describe('StructureDefinitionExporter R4', () => {
       );
     });
 
+    it('should remove inherited top-level underscore-prefixed metadata properties for an extension', () => {
+      const jsonModifiedPatientMothersMaidenName = defs.fishForFHIR('patient-mothersMaidenName');
+      jsonModifiedPatientMothersMaidenName.id = 'ModifiedPatientMothersMaidenName';
+      jsonModifiedPatientMothersMaidenName.name = 'ModifiedPatientMothersMaidenName';
+      jsonModifiedPatientMothersMaidenName.url =
+        'http://example.org/sd/ModifiedPatientMothersMaidenName';
+      jsonModifiedPatientMothersMaidenName._baseDefinition = {
+        extension: [
+          {
+            url: 'http://hl7.org/fhir/StructureDefinition/structuredefinition-codegen-super',
+            valueString: 'MetadataResource'
+          }
+        ]
+      };
+      pkg.extensions.push(StructureDefinition.fromJSON(jsonModifiedPatientMothersMaidenName));
+
+      const extension = new Extension('Foo');
+      extension.parent = 'ModifiedPatientMothersMaidenName';
+      doc.extensions.set(extension.name, extension);
+      exporter.exportStructDef(extension);
+      const exported = pkg.extensions[1];
+      expect(exported.baseDefinition).toBe(
+        'http://example.org/sd/ModifiedPatientMothersMaidenName'
+      ); // url for ModifiedPatientMothersMaidenName
+      // @ts-ignore
+      expect(exported._baseDefinition).toBeUndefined(); // should be stripped out
+    });
+
     it('should not overwrite metadata that is not given for an extension', () => {
       const extension = new Extension('Foo');
       doc.extensions.set(extension.name, extension);
@@ -1425,6 +1478,31 @@ describe('StructureDefinitionExporter R4', () => {
       expect(exported.derivation).toBe('specialization'); // always specialization for logical models
     });
 
+    it('should remove inherited top-level underscore-prefixed metadata properties for a logical model', () => {
+      const jsonModifiedAltID = defs.fishForFHIR('AlternateIdentification');
+      jsonModifiedAltID.id = 'ModifiedAlternateIdentification';
+      jsonModifiedAltID.name = 'ModifiedAlternateIdentification';
+      jsonModifiedAltID.url = 'http://example.org/sd/ModifiedAlternateIdentification';
+      jsonModifiedAltID._baseDefinition = {
+        extension: [
+          {
+            url: 'http://hl7.org/fhir/StructureDefinition/structuredefinition-codegen-super',
+            valueString: 'MetadataResource'
+          }
+        ]
+      };
+      pkg.logicals.push(StructureDefinition.fromJSON(jsonModifiedAltID));
+
+      const logical = new Logical('Foo');
+      logical.parent = 'ModifiedAlternateIdentification';
+      doc.logicals.set(logical.name, logical);
+      exporter.exportStructDef(logical);
+      const exported = pkg.logicals[1];
+      expect(exported.baseDefinition).toBe('http://example.org/sd/ModifiedAlternateIdentification'); // url for ModifiedObservation
+      // @ts-ignore
+      expect(exported._baseDefinition).toBeUndefined(); // should be stripped out
+    });
+
     it('should not overwrite metadata that is not given for a logical model', () => {
       const logical = new Logical('Foo');
       doc.logicals.set(logical.name, logical);
@@ -1725,6 +1803,33 @@ describe('StructureDefinitionExporter R4', () => {
       expect(exported.derivation).toBe('specialization'); // always specialization for resource
     });
 
+    it('should remove inherited top-level underscore-prefixed metadata properties for a resource', () => {
+      const jsonModifiedResource = defs.fishForFHIR('Resource');
+      jsonModifiedResource.id = 'ModifiedResource';
+      jsonModifiedResource.name = 'ModifiedResource';
+      jsonModifiedResource.url = 'http://example.org/sd/ModifiedResource';
+      jsonModifiedResource._baseDefinition = {
+        extension: [
+          {
+            url: 'http://hl7.org/fhir/StructureDefinition/structuredefinition-codegen-super',
+            valueString: 'MetadataResource'
+          }
+        ]
+      };
+      pkg.resources.push(StructureDefinition.fromJSON(jsonModifiedResource));
+
+      const resource = new Resource('Foo');
+      resource.parent = 'ModifiedResource';
+      resource.title = 'Custom Foo Resource';
+      resource.description = 'foo bar foobar';
+      doc.resources.set(resource.name, resource);
+      exporter.exportStructDef(resource);
+      const exported = pkg.resources[1];
+      expect(exported.baseDefinition).toBe('http://example.org/sd/ModifiedResource'); // url for ModifiedObservation
+      // @ts-ignore
+      expect(exported._baseDefinition).toBeUndefined(); // should be stripped out
+    });
+
     it('should not overwrite metadata that is not given for a resource', () => {
       const resource = new Resource('Foo');
       doc.resources.set(resource.name, resource);
diff --git a/test/fhirtypes/ElementDefinition.constrainType.test.ts b/test/fhirtypes/ElementDefinition.constrainType.test.ts
index a286369..bf4ff74 100644
--- a/test/fhirtypes/ElementDefinition.constrainType.test.ts
+++ b/test/fhirtypes/ElementDefinition.constrainType.test.ts
@@ -2,7 +2,7 @@ import { loadFromPath } from 'fhir-package-loader';
 import { TestFisher, loggerSpy } from '../testhelpers';
 import { FHIRDefinitions } from '../../src/fhirdefs/FHIRDefinitions';
 import { StructureDefinition } from '../../src/fhirtypes/StructureDefinition';
-import { ElementDefinitionType } from '../../src/fhirtypes';
+import { ElementDefinitionType, LooseElementDefJSON } from '../../src/fhirtypes';
 import { Type } from '../../src/utils';
 import { OnlyRule } from '../../src/fshtypes/rules';
 import { readFileSync } from 'fs-extra';
@@ -16,6 +16,8 @@ import path from 'path';
 describe('ElementDefinition', () => {
   let defs: FHIRDefinitions;
   let observation: StructureDefinition;
+  let jsonModifiedObservation: any;
+  let modifiedObservation: StructureDefinition;
   let planDefinition: StructureDefinition;
   let extension: StructureDefinition;
   let fisher: TestFisher;
@@ -27,12 +29,70 @@ describe('ElementDefinition', () => {
     loadFromPath(path.join(__dirname, '..', 'testhelpers', 'testdefs'), 'r4-definitions', defs);
     pkg = new Package(minimalConfig);
     fisher = new TestFisher().withFHIR(defs).withPackage(pkg);
+    jsonModifiedObservation = cloneDeep(defs.fishForFHIR('Observation', Type.Resource));
+    const createExtra = (id: string, ms: boolean) => {
+      return {
+        id,
+        extension: [
+          {
+            url: 'http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support',
+            valueBoolean: ms
+          }
+        ]
+      };
+    };
+    const identifier = jsonModifiedObservation.snapshot.element.find(
+      (e: LooseElementDefJSON) => e.id === 'Observation.identifier'
+    );
+    identifier.type[0].profile = [
+      'http://example.org/identifiers/StructureDefinition/required-type-identifier',
+      'http://example.org/identifiers/StructureDefinition/required-use-identifier',
+      'http://example.org/identifiers/StructureDefinition/required-value-identifier'
+    ];
+    identifier.type[0]._profile = [
+      createExtra('type-extra', true),
+      null,
+      createExtra('value-extra', true)
+    ];
+    const focus = jsonModifiedObservation.snapshot.element.find(
+      (e: LooseElementDefJSON) => e.id === 'Observation.focus'
+    );
+    focus.type[0]._targetProfile = [createExtra('any-extra', true)];
+    const hasMember = jsonModifiedObservation.snapshot.element.find(
+      (e: LooseElementDefJSON) => e.id === 'Observation.hasMember'
+    );
+    hasMember.type[0]._targetProfile = [
+      createExtra('observation-extra', true),
+      createExtra('questionnaire-response-extra', true),
+      null
+    ];
+    const subject = jsonModifiedObservation.snapshot.element.find(
+      (e: LooseElementDefJSON) => e.id === 'Observation.subject'
+    );
+    subject.type[0]._targetProfile = [
+      createExtra('patient-extra', true),
+      createExtra('group-extra', true),
+      null,
+      null
+    ];
+    const performer = jsonModifiedObservation.snapshot.element.find(
+      (e: LooseElementDefJSON) => e.id === 'Observation.performer'
+    );
+    performer.type[0]._targetProfile = [
+      createExtra('practitioner-extra', true),
+      null,
+      createExtra('organization-extra', false),
+      createExtra('care-team-extra', false),
+      null,
+      createExtra('related-person-extra', true)
+    ];
     exporter = new StructureDefinitionExporter(new FSHTank([], minimalConfig), pkg, fisher);
   });
 
   beforeEach(() => {
     loggerSpy.reset();
     observation = fisher.fishForStructureDefinition('Observation');
+    modifiedObservation = StructureDefinition.fromJSON(jsonModifiedObservation);
     planDefinition = fisher.fishForStructureDefinition('PlanDefinition');
     extension = fisher.fishForStructureDefinition('Extension');
   });
@@ -182,6 +242,113 @@ describe('ElementDefinition', () => {
       );
     });
 
+    it('should remove a _profile entry when a set of profiles is constrained to a subset of profiles', () => {
+      const identifier = modifiedObservation.elements.find(e => e.id === 'Observation.identifier');
+      const identifierConstraint = new OnlyRule('entry.resource');
+      identifierConstraint.types = [
+        { type: 'required-use-identifier' },
+        { type: 'required-value-identifier' }
+      ];
+      identifier.constrainType(identifierConstraint, fisher);
+      const expectedType = new ElementDefinitionType('Identifier').withProfiles(
+        'http://example.org/identifiers/StructureDefinition/required-use-identifier',
+        'http://example.org/identifiers/StructureDefinition/required-value-identifier'
+      );
+      expectedType._profile = [
+        null,
+        {
+          id: 'value-extra',
+          extension: [
+            {
+              url: 'http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support',
+              valueBoolean: true
+            }
+          ]
+        }
+      ];
+      expect(identifier.type).toHaveLength(1);
+      expect(identifier.type[0]).toEqual(expectedType);
+    });
+
+    it('should null a _profile entry when a profile is constrained to a more specific profile', () => {
+      const identifier = modifiedObservation.elements.find(e => e.id === 'Observation.identifier');
+      const identifierConstraint = new OnlyRule('entry.resource');
+      identifierConstraint.types = [
+        { type: 'required-type-identifier' },
+        { type: 'required-use-identifier' },
+        { type: 'required-system-value-identifier' }
+      ];
+      identifier.constrainType(identifierConstraint, fisher);
+      const expectedType = new ElementDefinitionType('Identifier').withProfiles(
+        'http://example.org/identifiers/StructureDefinition/required-type-identifier',
+        'http://example.org/identifiers/StructureDefinition/required-use-identifier',
+        'http://example.org/identifiers/StructureDefinition/required-system-value-identifier'
+      );
+      expectedType._profile = [
+        {
+          id: 'type-extra',
+          extension: [
+            {
+              url: 'http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support',
+              valueBoolean: true
+            }
+          ]
+        },
+        null,
+        null
+      ];
+      expect(identifier.type).toHaveLength(1);
+      expect(identifier.type[0]).toEqual(expectedType);
+    });
+
+    it('should null multiple _profile entries when a profile is constrained to multiple more specific profiles', () => {
+      const identifier = modifiedObservation.elements.find(e => e.id === 'Observation.identifier');
+      const identifierConstraint = new OnlyRule('entry.resource');
+      identifierConstraint.types = [
+        { type: 'required-type-identifier' },
+        { type: 'required-use-identifier' },
+        { type: 'required-system-value-identifier' },
+        { type: 'required-type-value-identifier' }
+      ];
+      identifier.constrainType(identifierConstraint, fisher);
+      const expectedType = new ElementDefinitionType('Identifier').withProfiles(
+        'http://example.org/identifiers/StructureDefinition/required-type-identifier',
+        'http://example.org/identifiers/StructureDefinition/required-use-identifier',
+        'http://example.org/identifiers/StructureDefinition/required-system-value-identifier',
+        'http://example.org/identifiers/StructureDefinition/required-type-value-identifier'
+      );
+      expectedType._profile = [
+        {
+          id: 'type-extra',
+          extension: [
+            {
+              url: 'http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support',
+              valueBoolean: true
+            }
+          ]
+        },
+        null,
+        null,
+        null
+      ];
+      expect(identifier.type).toHaveLength(1);
+      expect(identifier.type[0]).toEqual(expectedType);
+    });
+
+    it('should remove _profile array when only null values are left', () => {
+      const identifier = modifiedObservation.elements.find(e => e.id === 'Observation.identifier');
+      const identifierConstraint = new OnlyRule('entry.resource');
+      identifierConstraint.types = [{ type: 'required-use-identifier' }];
+      identifier.constrainType(identifierConstraint, fisher);
+      expect(identifier.type).toHaveLength(1);
+      expect(identifier.type[0]).toEqual(
+        new ElementDefinitionType('Identifier').withProfiles(
+          'http://example.org/identifiers/StructureDefinition/required-use-identifier'
+        )
+        // NOTE: no _profile array
+      );
+    });
+
     it('should allow a profile to be constrained to a more specific profile of a child type', () => {
       const bundle = fisher.fishForStructureDefinition('Bundle');
       const entryResource = bundle.elements.find(e => e.id === 'Bundle.entry.resource');
@@ -294,6 +461,60 @@ describe('ElementDefinition', () => {
       );
     });
 
+    it('should correctly modify _targetProfile array when multiple resource types are constrained to a reference to a subset', () => {
+      const performer = modifiedObservation.elements.find(e => e.id === 'Observation.performer');
+      const performerConstraint = new OnlyRule('performer');
+      performerConstraint.types = [
+        { type: 'Practitioner', isReference: true },
+        { type: 'Organization', isReference: true }
+      ];
+      performer.constrainType(performerConstraint, fisher);
+      const expectedType = new ElementDefinitionType('Reference').withTargetProfiles(
+        'http://hl7.org/fhir/StructureDefinition/Practitioner',
+        'http://hl7.org/fhir/StructureDefinition/Organization'
+      );
+      expectedType._targetProfile = [
+        {
+          id: 'practitioner-extra',
+          extension: [
+            {
+              url: 'http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support',
+              valueBoolean: true
+            }
+          ]
+        },
+        {
+          id: 'organization-extra',
+          extension: [
+            {
+              url: 'http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support',
+              valueBoolean: false
+            }
+          ]
+        }
+      ];
+      expect(performer.type).toHaveLength(1);
+      expect(performer.type[0]).toEqual(expectedType);
+    });
+
+    it('should remove _targetProfile array when only values are null after constraining types', () => {
+      const performer = modifiedObservation.elements.find(e => e.id === 'Observation.performer');
+      const performerConstraint = new OnlyRule('performer');
+      performerConstraint.types = [
+        { type: 'PractitionerRole', isReference: true },
+        { type: 'Patient', isReference: true }
+      ];
+      performer.constrainType(performerConstraint, fisher);
+      expect(performer.type).toHaveLength(1);
+      expect(performer.type[0]).toEqual(
+        new ElementDefinitionType('Reference').withTargetProfiles(
+          'http://hl7.org/fhir/StructureDefinition/PractitionerRole',
+          'http://hl7.org/fhir/StructureDefinition/Patient'
+        )
+        // NOTE: No _targetProfile array
+      );
+    });
+
     it('should allow a reference to multiple resource types to be constrained to a reference to a single type', () => {
       const performer = observation.elements.find(e => e.id === 'Observation.performer');
       const performerConstraint = new OnlyRule('performer');
@@ -322,6 +543,34 @@ describe('ElementDefinition', () => {
       );
     });
 
+    it('should null _targetProfile entry when a resource type in a reference is constrained to a single profile', () => {
+      const subject = modifiedObservation.elements.find(e => e.id === 'Observation.subject');
+      const subjectConstraint = new OnlyRule('subject');
+      subjectConstraint.types = [
+        { type: 'Patient', isReference: true },
+        { type: 'http://hl7.org/fhir/StructureDefinition/actualgroup', isReference: true }
+      ];
+      subject.constrainType(subjectConstraint, fisher);
+      const expectedType = new ElementDefinitionType('Reference').withTargetProfiles(
+        'http://hl7.org/fhir/StructureDefinition/Patient',
+        'http://hl7.org/fhir/StructureDefinition/actualgroup'
+      );
+      expectedType._targetProfile = [
+        {
+          id: 'patient-extra',
+          extension: [
+            {
+              url: 'http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support',
+              valueBoolean: true
+            }
+          ]
+        },
+        null
+      ];
+      expect(subject.type).toHaveLength(1);
+      expect(subject.type[0]).toEqual(expectedType);
+    });
+
     it('should allow a resource type in a reference to multiple types to be constrained to multiple profiles', () => {
       const hasMember = observation.elements.find(e => e.id === 'Observation.hasMember');
       const hasMemberConstraint = new OnlyRule('hasMember');
@@ -339,6 +588,40 @@ describe('ElementDefinition', () => {
       );
     });
 
+    it('should null multiple _targetProfile entries when a resource type in a reference to multiple types is constrained to multiple profiles', () => {
+      const hasMember = modifiedObservation.elements.find(e => e.id === 'Observation.hasMember');
+      const hasMemberConstraint = new OnlyRule('hasMember');
+      hasMemberConstraint.types = [
+        { type: 'http://hl7.org/fhir/StructureDefinition/bodyheight', isReference: true },
+        { type: 'http://hl7.org/fhir/StructureDefinition/bodyweight', isReference: true },
+        {
+          type: 'http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse',
+          isReference: true
+        }
+      ];
+      hasMember.constrainType(hasMemberConstraint, fisher);
+      const expectedType = new ElementDefinitionType('Reference').withTargetProfiles(
+        'http://hl7.org/fhir/StructureDefinition/bodyheight',
+        'http://hl7.org/fhir/StructureDefinition/bodyweight',
+        'http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse'
+      );
+      expectedType._targetProfile = [
+        null,
+        null,
+        {
+          id: 'questionnaire-response-extra',
+          extension: [
+            {
+              url: 'http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support',
+              valueBoolean: true
+            }
+          ]
+        }
+      ];
+      expect(hasMember.type).toHaveLength(1);
+      expect(hasMember.type[0]).toEqual(expectedType);
+    });
+
     it('should allow us to constrain a reference to a profile whose parent is specified using a versioned canonical URL', () => {
       const hasMember = observation.elements.find(e => e.id === 'Observation.hasMember');
       const hasMemberConstraint = new OnlyRule('hasMember');
@@ -431,6 +714,20 @@ describe('ElementDefinition', () => {
       );
     });
 
+    it('should remove _targetProfile when a reference to Any is constrained to a reference to a resource', () => {
+      const focus = modifiedObservation.elements.find(e => e.id === 'Observation.focus');
+      const focusConstraint = new OnlyRule('focus');
+      focusConstraint.types = [{ type: 'Practitioner', isReference: true }];
+      focus.constrainType(focusConstraint, fisher);
+      expect(focus.type).toHaveLength(1);
+      expect(focus.type[0]).toEqual(
+        new ElementDefinitionType('Reference').withTargetProfiles(
+          'http://hl7.org/fhir/StructureDefinition/Practitioner'
+        )
+        // NOTE: No _targetProfile array
+      );
+    });
+
     it('should allow a reference to Any to be constrained to a reference to a profile', () => {
       const focus = observation.elements.find(e => e.id === 'Observation.focus');
       const focusConstraint = new OnlyRule('focus');
@@ -482,6 +779,38 @@ describe('ElementDefinition', () => {
       );
     });
 
+    it('should null multiple _targetProfile entries when a reference to multiple resource types is constrained such that only the target reference is constrained and others remain as-is', () => {
+      const hasMember = modifiedObservation.elements.find(e => e.id === 'Observation.hasMember');
+      const hasMemberConstraint = new OnlyRule('hasMember');
+      hasMemberConstraint.types = [
+        { type: 'http://hl7.org/fhir/StructureDefinition/bodyheight', isReference: true },
+        { type: 'http://hl7.org/fhir/StructureDefinition/bodyweight', isReference: true }
+      ];
+      hasMember.constrainType(hasMemberConstraint, fisher, 'Observation');
+      const expectedType = new ElementDefinitionType('Reference').withTargetProfiles(
+        'http://hl7.org/fhir/StructureDefinition/bodyheight',
+        'http://hl7.org/fhir/StructureDefinition/bodyweight',
+        'http://hl7.org/fhir/StructureDefinition/QuestionnaireResponse',
+        'http://hl7.org/fhir/StructureDefinition/MolecularSequence'
+      );
+      expectedType._targetProfile = [
+        null,
+        null,
+        {
+          id: 'questionnaire-response-extra',
+          extension: [
+            {
+              url: 'http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support',
+              valueBoolean: true
+            }
+          ]
+        },
+        null
+      ];
+      expect(hasMember.type).toHaveLength(1);
+      expect(hasMember.type[0]).toEqual(expectedType);
+    });
+
     // start canonicals
 
     it('should allow a canonical to multiple resource types to be constrained to a canonical to a subset', () => {
diff --git a/test/fhirtypes/ElementDefinition.test.ts b/test/fhirtypes/ElementDefinition.test.ts
index 213a8f0..62f7e1c 100644
--- a/test/fhirtypes/ElementDefinition.test.ts
+++ b/test/fhirtypes/ElementDefinition.test.ts
@@ -14,10 +14,16 @@ describe('ElementDefinition', () => {
   let jsonObservation: any;
   let jsonValueX: any;
   let jsonValueId: any;
+  let jsonModifiedObservation: any;
+  let jsonModifiedStatus: any;
+  let jsonModifiedSubject: any;
   let observation: StructureDefinition;
   let resprate: StructureDefinition;
   let valueX: ElementDefinition;
   let valueId: ElementDefinition;
+  let modifiedObservation: StructureDefinition;
+  let modifiedStatus: ElementDefinition;
+  let modifiedSubject: ElementDefinition;
   let fisher: TestFisher;
   beforeAll(() => {
     defs = new FHIRDefinitions();
@@ -29,6 +35,29 @@ describe('ElementDefinition', () => {
     jsonObservation = defs.fishForFHIR('Observation', Type.Resource);
     jsonValueX = jsonObservation.snapshot.element[21];
     jsonValueId = jsonObservation.snapshot.element[1];
+    jsonModifiedObservation = cloneDeep(jsonObservation);
+    jsonModifiedStatus = jsonModifiedObservation.snapshot.element[12];
+    jsonModifiedStatus._short = {
+      id: 'short-id',
+      extension: {
+        url: 'http://example.org/extensions/short',
+        valueString: 'bogus'
+      }
+    };
+    jsonModifiedSubject = jsonModifiedObservation.snapshot.element[15];
+    jsonModifiedSubject.type[0]._targetProfile = [
+      null,
+      null,
+      {
+        extension: [
+          {
+            url: 'http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support',
+            valueBoolean: true
+          }
+        ]
+      },
+      null
+    ];
   });
   beforeEach(() => {
     observation = StructureDefinition.fromJSON(jsonObservation);
@@ -37,6 +66,11 @@ describe('ElementDefinition', () => {
     valueId = ElementDefinition.fromJSON(jsonValueId);
     valueX.structDef = observation;
     valueId.structDef = observation;
+    modifiedObservation = StructureDefinition.fromJSON(jsonModifiedObservation);
+    modifiedStatus = ElementDefinition.fromJSON(jsonModifiedStatus);
+    modifiedSubject = ElementDefinition.fromJSON(jsonModifiedSubject);
+    modifiedStatus.structDef = modifiedObservation;
+    modifiedSubject.structDef = modifiedObservation;
     loggerSpy.reset();
   });
 
@@ -86,6 +120,47 @@ describe('ElementDefinition', () => {
         new ElementDefinitionType('Period')
       ]);
     });
+
+    it('should load primitive property ids and extensions', () => {
+      expect(modifiedStatus.hasDiff()).toBeFalsy();
+      expect(modifiedStatus.id).toBe('Observation.status');
+      expect(modifiedStatus.path).toBe('Observation.status');
+      expect(modifiedStatus.short).toBe('registered | preliminary | final | amended +');
+      // @ts-ignore
+      expect(modifiedStatus._short).toEqual({
+        id: 'short-id',
+        extension: {
+          url: 'http://example.org/extensions/short',
+          valueString: 'bogus'
+        }
+      });
+    });
+
+    it('should load property ids and extensions on type targetProfiles', () => {
+      expect(modifiedSubject.hasDiff()).toBeFalsy();
+      expect(modifiedSubject.id).toBe('Observation.subject');
+      expect(modifiedSubject.path).toBe('Observation.subject');
+      expect(modifiedSubject.type[0].code).toBe('Reference');
+      expect(modifiedSubject.type[0].targetProfile).toEqual([
+        'http://hl7.org/fhir/StructureDefinition/Patient',
+        'http://hl7.org/fhir/StructureDefinition/Group',
+        'http://hl7.org/fhir/StructureDefinition/Device',
+        'http://hl7.org/fhir/StructureDefinition/Location'
+      ]);
+      expect(modifiedSubject.type[0]._targetProfile).toEqual([
+        null,
+        null,
+        {
+          extension: [
+            {
+              url: 'http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support',
+              valueBoolean: true
+            }
+          ]
+        },
+        null
+      ]);
+    });
   });
 
   describe('#toJSON', () => {
@@ -93,6 +168,16 @@ describe('ElementDefinition', () => {
       const newJSON = valueX.toJSON();
       expect(newJSON).toEqual(jsonValueX);
     });
+
+    it('should round trip back to the original JSON when there are ids and extensions on primitives', () => {
+      const newJSON = modifiedStatus.toJSON();
+      expect(newJSON).toEqual(jsonModifiedStatus);
+    });
+
+    it('should round trip back to the original JSON when there are ids and extensions on type targetProfiles', () => {
+      const newJSON = modifiedSubject.toJSON();
+      expect(newJSON).toEqual(jsonModifiedSubject);
+    });
   });
 
   describe('#id()', () => {
@@ -255,6 +340,30 @@ describe('ElementDefinition', () => {
       expect(valueX.hasDiff()).toBeFalsy();
     });
 
+    it('should detect diff correctly with id and extension on a primitive', () => {
+      // @ts-ignore
+      modifiedStatus._short.id = 'short-id';
+      modifiedStatus.captureOriginal();
+      // @ts-ignore
+      modifiedStatus._short.id = 'not-as-short-id';
+      expect(modifiedStatus.hasDiff()).toBeTruthy();
+      // @ts-ignore
+      modifiedStatus._short.id = 'short-id';
+      expect(modifiedStatus.hasDiff()).toBeFalsy();
+    });
+
+    it('should detect diff correctly with id and extension on a type targetProfile', () => {
+      // @ts-ignore
+      modifiedSubject.type[0]._targetProfile[2].extension[0].valueBoolean = true;
+      modifiedSubject.captureOriginal();
+      // @ts-ignore
+      modifiedSubject.type[0]._targetProfile[2].extension[0].valueBoolean = false;
+      expect(modifiedSubject.hasDiff()).toBeTruthy();
+      // @ts-ignore
+      modifiedSubject.type[0]._targetProfile[2].extension[0].valueBoolean = true;
+      expect(modifiedSubject.hasDiff()).toBeFalsy();
+    });
+
     it('should detect diffs and non-diffs correctly when elements are unfolded', () => {
       const code = observation.elements.find(e => e.id === 'Observation.code');
       code.unfold(fisher);
@@ -385,6 +494,61 @@ describe('ElementDefinition', () => {
       expect(Object.keys(diff.toJSON())).toHaveLength(3);
     });
 
+    it('should calculate diff correctly with id and extension on a primitive element', () => {
+      // @ts-ignore
+      modifiedStatus._short.id = 'short-id';
+      modifiedStatus.captureOriginal();
+      // @ts-ignore
+      modifiedStatus._short.id = 'not-as-short-id';
+      const diff = modifiedStatus.calculateDiff();
+      expect(diff.id).toBe('Observation.status');
+      expect(diff.path).toBe('Observation.status');
+      // NOTE: We diff property by property, but diffs are not deep. So diff contains whole _short.
+      // @ts-ignore
+      expect(diff._short).toEqual({
+        id: 'not-as-short-id',
+        extension: {
+          url: 'http://example.org/extensions/short',
+          valueString: 'bogus'
+        }
+      });
+      expect(Object.keys(diff.toJSON())).toHaveLength(3);
+    });
+
+    it('should calculate diff correctly with id and extension on a type targetProfile', () => {
+      // @ts-ignore
+      modifiedSubject.type[0]._targetProfile[2].extension[0].valueBoolean = true;
+      modifiedSubject.captureOriginal();
+      // @ts-ignore
+      modifiedSubject.type[0]._targetProfile[2].extension[0].valueBoolean = false;
+      const diff = modifiedSubject.calculateDiff();
+      expect(diff.id).toBe('Observation.subject');
+      expect(diff.path).toBe('Observation.subject');
+      // NOTE: We diff property by property, but diffs are not deep. So diff contains whole type.
+      // @ts-ignore
+      expect(diff.type[0].code).toBe('Reference');
+      expect(diff.type[0].targetProfile).toEqual([
+        'http://hl7.org/fhir/StructureDefinition/Patient',
+        'http://hl7.org/fhir/StructureDefinition/Group',
+        'http://hl7.org/fhir/StructureDefinition/Device',
+        'http://hl7.org/fhir/StructureDefinition/Location'
+      ]);
+      expect(diff.type[0]._targetProfile).toEqual([
+        null,
+        null,
+        {
+          extension: [
+            {
+              url: 'http://hl7.org/fhir/StructureDefinition/elementdefinition-type-must-support',
+              valueBoolean: false
+            }
+          ]
+        },
+        null
+      ]);
+      expect(Object.keys(diff.toJSON())).toHaveLength(3);
+    });
+
     it('should include only new constraints in a diff when constraints are added', () => {
       const myInvariant = new Invariant('inv-1');
       myInvariant.severity = new FshCode('warning');
diff --git a/test/fhirtypes/StructureDefinition.test.ts b/test/fhirtypes/StructureDefinition.test.ts
index 3de643b..2009606 100644
--- a/test/fhirtypes/StructureDefinition.test.ts
+++ b/test/fhirtypes/StructureDefinition.test.ts
@@ -13,11 +13,14 @@ import { FSHDocument, FSHTank } from '../../src/import';
 import { minimalConfig } from '../utils/minimalConfig';
 import { Package, StructureDefinitionExporter } from '../../src/export';
 import { ValidationError } from '../../src/errors';
+import { cloneDeep } from 'lodash';
 
 describe('StructureDefinition', () => {
   let defs: FHIRDefinitions;
   let jsonObservation: any;
   let observation: StructureDefinition;
+  let jsonModifiedObservation: any;
+  let modifiedObservation: StructureDefinition;
   let jsonPlanDefinition: any;
   let planDefinition: StructureDefinition;
   let resprate: StructureDefinition;
@@ -32,6 +35,16 @@ describe('StructureDefinition', () => {
     // resolve observation once to ensure it is present in defs
     observation = fisher.fishForStructureDefinition('Observation');
     jsonObservation = defs.fishForFHIR('Observation', Type.Resource);
+    jsonModifiedObservation = cloneDeep(jsonObservation);
+    jsonModifiedObservation._baseDefinition = {
+      id: 'baseDefinition-extension',
+      extension: [
+        {
+          url: 'http://hl7.org/fhir/StructureDefinition/structuredefinition-codegen-super',
+          valueString: 'MetadataResource'
+        }
+      ]
+    };
     usCoreObservation = fisher.fishForStructureDefinition('us-core-observation-lab');
     jsonUsCoreObservation = defs.fishForFHIR('us-core-observation-lab', Type.Profile);
     planDefinition = fisher.fishForStructureDefinition('PlanDefinition');
@@ -40,6 +53,7 @@ describe('StructureDefinition', () => {
 
   beforeEach(() => {
     observation = StructureDefinition.fromJSON(jsonObservation);
+    modifiedObservation = StructureDefinition.fromJSON(jsonModifiedObservation);
     planDefinition = StructureDefinition.fromJSON(jsonPlanDefinition);
     usCoreObservation = StructureDefinition.fromJSON(jsonUsCoreObservation);
     resprate = fisher.fishForStructureDefinition('resprate');
@@ -77,6 +91,24 @@ describe('StructureDefinition', () => {
       ]);
     });
 
+    it('should load a resource properly when there are ids and extensions on primitives', () => {
+      // Don't test everything, but get a sample anyway
+      expect(modifiedObservation.id).toBe('Observation');
+      expect(modifiedObservation.baseDefinition).toBe(
+        'http://hl7.org/fhir/StructureDefinition/DomainResource'
+      );
+      // @ts-ignore
+      expect(modifiedObservation._baseDefinition).toEqual({
+        id: 'baseDefinition-extension',
+        extension: [
+          {
+            url: 'http://hl7.org/fhir/StructureDefinition/structuredefinition-codegen-super',
+            valueString: 'MetadataResource'
+          }
+        ]
+      });
+    });
+
     it('should load a resource properly without capturing originals', () => {
       observation = StructureDefinition.fromJSON(jsonObservation, false);
       // Don't test everything, but get a sample anyway
@@ -120,11 +152,24 @@ describe('StructureDefinition', () => {
   });
 
   describe('#toJSON', () => {
-    // Skipping because the differential doesn't come back right.
-    // Need to re-evaluate how we do differentials.
-    it.skip('should round trip back to the original JSON', () => {
+    it('should round trip back to the original JSON (excepting differentials)', () => {
+      const oldJSON = cloneDeep(jsonObservation);
       const newJSON = observation.toJSON();
-      expect(newJSON).toEqual(jsonObservation);
+      // Because of the way we do differentials, those won't come back the same,
+      // so remove differentials before comparing.
+      delete oldJSON.differential;
+      delete newJSON.differential;
+      expect(newJSON).toEqual(oldJSON);
+    });
+
+    it('should round trip back to the original JSON when there are ids and extensions on primitives (excepting differentials)', () => {
+      const oldJSON = cloneDeep(jsonModifiedObservation);
+      const newJSON = modifiedObservation.toJSON();
+      // Because of the way we do differentials, those won't come back the same,
+      // so remove differentials before comparing.
+      delete oldJSON.differential;
+      delete newJSON.differential;
+      expect(newJSON).toEqual(oldJSON);
     });
 
     it('should reflect differentials for elements that changed after capturing originals', () => {
diff --git a/test/testhelpers/testdefs/r4-definitions/package/StructureDefinition-required-system-value-identifier.json b/test/testhelpers/testdefs/r4-definitions/package/StructureDefinition-required-system-value-identifier.json
new file mode 100644
index 0000000..bb584ef
--- /dev/null
+++ b/test/testhelpers/testdefs/r4-definitions/package/StructureDefinition-required-system-value-identifier.json
@@ -0,0 +1,432 @@
+{
+  "resourceType" : "StructureDefinition",
+  "id" : "required-system-value-identifier",
+  "text" : {
+    "status" : "extensions",
+    "div" : "<div xmlns=\"http://www.w3.org/1999/xhtml\"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" style=\"border: 0px #F0F0F0 solid; font-size: 11px; font-family: verdana; vertical-align: top;\"><tr style=\"border: 1px #F0F0F0 solid; font-size: 11px; font-family: verdana; vertical-align: top\"><th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"The logical name of the element\">Name</a></th><th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Information about the use of the element\">Flags</a></th><th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Minimum and Maximum # of times the the element can appear in the instance\">Card.</a></th><th style=\"width: 100px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Reference to the type of the element\">Type</a></th><th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Additional information about the element\">Description &amp; Constraints</a><span style=\"float: right\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Legend for this format\"><img src=\"http://hl7.org/fhir/R4/help16.png\" alt=\"doco\" style=\"background-color: inherit\"/></a></span></th></tr><tr style=\"border: 0px #F0F0F0 solid; padding:0px; vertical-align: top; background-color: white\"><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px; white-space: nowrap; background-image: url(tbl_bck1.png)\" class=\"hierarchy\"><img src=\"tbl_spacer.png\" alt=\".\" style=\"background-color: inherit\" class=\"hierarchy\"/><img src=\"icon_element.gif\" alt=\".\" style=\"background-color: white; background-color: inherit\" title=\"Element\" class=\"hierarchy\"/> <a href=\"StructureDefinition-required-system-value-identifier-definitions.html#Identifier\">Identifier</a><a name=\"Identifier\"> </a></td><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"/><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><span style=\"opacity: 0.5\">0</span><span style=\"opacity: 0.5\">..</span><span style=\"opacity: 0.5\">*</span></td><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"StructureDefinition-required-value-identifier.html\">RequiredValueIdentifier</a></td><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><span style=\"opacity: 0.5\">An identifier intended for computation</span></td></tr>\r\n<tr style=\"border: 0px #F0F0F0 solid; padding:0px; vertical-align: top; background-color: #F7F7F7\"><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px; white-space: nowrap; background-image: url(tbl_bck00.png)\" class=\"hierarchy\"><img src=\"tbl_spacer.png\" alt=\".\" style=\"background-color: inherit\" class=\"hierarchy\"/><img src=\"tbl_vjoin_end.png\" alt=\".\" style=\"background-color: inherit\" class=\"hierarchy\"/><img src=\"icon_element.gif\" alt=\".\" style=\"background-color: #F7F7F7; background-color: inherit\" title=\"Element\" class=\"hierarchy\"/> <a href=\"StructureDefinition-required-system-value-identifier-definitions.html#Identifier.system\">system</a><a name=\"Identifier.system\"> </a></td><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"/><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\">1..<span style=\"opacity: 0.5\">1</span></td><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a style=\"opacity: 0.5\" href=\"http://hl7.org/fhir/R4/datatypes.html#uri\">uri</a></td><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><span style=\"opacity: 0.5\">The namespace for the identifier value</span></td></tr>\r\n<tr><td colspan=\"5\" class=\"hierarchy\"><br/><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Legend for this format\"><img src=\"http://hl7.org/fhir/R4/help16.png\" alt=\"doco\" style=\"background-color: inherit\"/> Documentation for this format</a></td></tr></table></div>"
+  },
+  "url" : "http://example.org/identifiers/StructureDefinition/required-system-value-identifier",
+  "version" : "0.1.0",
+  "name" : "RequiredSystemValueIdentifier",
+  "title" : "Required System and Value Identifier",
+  "status" : "active",
+  "date" : "2023-03-20T12:26:54-04:00",
+  "publisher" : "Example Publisher",
+  "contact" : [{
+    "name" : "Example Publisher",
+    "telecom" : [{
+      "system" : "url",
+      "value" : "http://example.org/example-publisher"
+    }]
+  }],
+  "description" : "An identifier profile that requires the system and value elements.",
+  "fhirVersion" : "4.0.1",
+  "mapping" : [{
+    "identity" : "v2",
+    "uri" : "http://hl7.org/v2",
+    "name" : "HL7 v2 Mapping"
+  },
+  {
+    "identity" : "rim",
+    "uri" : "http://hl7.org/v3",
+    "name" : "RIM Mapping"
+  },
+  {
+    "identity" : "servd",
+    "uri" : "http://www.omg.org/spec/ServD/1.0/",
+    "name" : "ServD"
+  }],
+  "kind" : "complex-type",
+  "abstract" : false,
+  "type" : "Identifier",
+  "baseDefinition" : "http://example.org/identifiers/StructureDefinition/required-value-identifier",
+  "derivation" : "constraint",
+  "snapshot" : {
+    "element" : [{
+      "id" : "Identifier",
+      "path" : "Identifier",
+      "short" : "An identifier intended for computation",
+      "definition" : "An identifier - identifies some entity uniquely and unambiguously. Typically this is used for business identifiers.",
+      "min" : 0,
+      "max" : "*",
+      "base" : {
+        "path" : "Identifier",
+        "min" : 0,
+        "max" : "*"
+      },
+      "condition" : ["ele-1"],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "mapping" : [{
+        "identity" : "rim",
+        "map" : "n/a"
+      },
+      {
+        "identity" : "v2",
+        "map" : "CX / EI (occasionally, more often EI maps to a resource id or a URL)"
+      },
+      {
+        "identity" : "rim",
+        "map" : "II - The Identifier class is a little looser than the v3 type II because it allows URIs as well as registered OIDs or GUIDs.  Also maps to Role[classCode=IDENT]"
+      },
+      {
+        "identity" : "servd",
+        "map" : "Identifier"
+      }]
+    },
+    {
+      "id" : "Identifier.id",
+      "path" : "Identifier.id",
+      "representation" : ["xmlAttr"],
+      "short" : "Unique id for inter-element referencing",
+      "definition" : "Unique id for the element within a resource (for internal references). This may be any string value that does not contain spaces.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Element.id",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "extension" : [{
+          "url" : "http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type",
+          "valueUrl" : "string"
+        }],
+        "code" : "http://hl7.org/fhirpath/System.String"
+      }],
+      "isModifier" : false,
+      "isSummary" : false,
+      "mapping" : [{
+        "identity" : "rim",
+        "map" : "n/a"
+      }]
+    },
+    {
+      "id" : "Identifier.extension",
+      "path" : "Identifier.extension",
+      "slicing" : {
+        "discriminator" : [{
+          "type" : "value",
+          "path" : "url"
+        }],
+        "description" : "Extensions are always sliced by (at least) url",
+        "rules" : "open"
+      },
+      "short" : "Additional content defined by implementations",
+      "definition" : "May be used to represent additional information that is not part of the basic definition of the element. To make the use of extensions safe and manageable, there is a strict set of governance  applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension.",
+      "comment" : "There can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions.  The use of extensions is what allows the FHIR specification to retain a core level of simplicity for everyone.",
+      "alias" : ["extensions",
+      "user content"],
+      "min" : 0,
+      "max" : "*",
+      "base" : {
+        "path" : "Element.extension",
+        "min" : 0,
+        "max" : "*"
+      },
+      "type" : [{
+        "code" : "Extension"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      },
+      {
+        "key" : "ext-1",
+        "severity" : "error",
+        "human" : "Must have either extensions or value[x], not both",
+        "expression" : "extension.exists() != value.exists()",
+        "xpath" : "exists(f:extension)!=exists(f:*[starts-with(local-name(.), \"value\")])",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Extension"
+      }],
+      "isModifier" : false,
+      "isSummary" : false,
+      "mapping" : [{
+        "identity" : "rim",
+        "map" : "n/a"
+      }]
+    },
+    {
+      "id" : "Identifier.use",
+      "path" : "Identifier.use",
+      "short" : "usual | official | temp | secondary | old (If known)",
+      "definition" : "The purpose of this identifier.",
+      "comment" : "Applications can assume that an identifier is permanent unless it explicitly says that it is temporary.",
+      "requirements" : "Allows the appropriate identifier for a particular context of use to be selected from among a set of identifiers.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.use",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "code"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : true,
+      "isModifierReason" : "This is labeled as \"Is Modifier\" because applications should not mistake a temporary id for a permanent one.",
+      "isSummary" : true,
+      "binding" : {
+        "extension" : [{
+          "url" : "http://hl7.org/fhir/StructureDefinition/elementdefinition-bindingName",
+          "valueString" : "IdentifierUse"
+        }],
+        "strength" : "required",
+        "description" : "Identifies the purpose for this identifier, if known .",
+        "valueSet" : "http://hl7.org/fhir/ValueSet/identifier-use|4.0.1"
+      },
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "N/A"
+      },
+      {
+        "identity" : "rim",
+        "map" : "Role.code or implied by context"
+      }]
+    },
+    {
+      "id" : "Identifier.type",
+      "path" : "Identifier.type",
+      "short" : "Description of identifier",
+      "definition" : "A coded type for the identifier that can be used to determine which identifier to use for a specific purpose.",
+      "comment" : "This element deals only with general categories of identifiers.  It SHOULD not be used for codes that correspond 1..1 with the Identifier.system. Some identifiers may fall into multiple categories due to common usage.   Where the system is known, a type is unnecessary because the type is always part of the system definition. However systems often need to handle identifiers where the system is not known. There is not a 1:1 relationship between type and system, since many different systems have the same type.",
+      "requirements" : "Allows users to make use of identifiers when the identifier system is not known.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.type",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "CodeableConcept"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "binding" : {
+        "extension" : [{
+          "url" : "http://hl7.org/fhir/StructureDefinition/elementdefinition-bindingName",
+          "valueString" : "IdentifierType"
+        },
+        {
+          "url" : "http://hl7.org/fhir/StructureDefinition/elementdefinition-isCommonBinding",
+          "valueBoolean" : true
+        }],
+        "strength" : "extensible",
+        "description" : "A coded type for an identifier that can be used to determine which identifier to use for a specific purpose.",
+        "valueSet" : "http://hl7.org/fhir/ValueSet/identifier-type"
+      },
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.5"
+      },
+      {
+        "identity" : "rim",
+        "map" : "Role.code or implied by context"
+      }]
+    },
+    {
+      "id" : "Identifier.system",
+      "path" : "Identifier.system",
+      "short" : "The namespace for the identifier value",
+      "definition" : "Establishes the namespace for the value - that is, a URL that describes a set values that are unique.",
+      "comment" : "Identifier.system is always case sensitive.",
+      "requirements" : "There are many sets  of identifiers.  To perform matching of two identifiers, we need to know what set we're dealing with. The system identifies a particular set of unique identifiers.",
+      "min" : 1,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.system",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "uri"
+      }],
+      "example" : [{
+        "label" : "General",
+        "valueUri" : "http://www.acme.com/identifiers/patient"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.4 / EI-2-4"
+      },
+      {
+        "identity" : "rim",
+        "map" : "II.root or Role.id.root"
+      },
+      {
+        "identity" : "servd",
+        "map" : "./IdentifierType"
+      }]
+    },
+    {
+      "id" : "Identifier.value",
+      "path" : "Identifier.value",
+      "short" : "The value that is unique",
+      "definition" : "The portion of the identifier typically relevant to the user and which is unique within the context of the system.",
+      "comment" : "If the value is a full URI, then the system SHALL be urn:ietf:rfc:3986.  The value's primary purpose is computational mapping.  As a result, it may be normalized for comparison purposes (e.g. removing non-significant whitespace, dashes, etc.)  A value formatted for human display can be conveyed using the [Rendered Value extension](http://hl7.org/fhir/R4/extension-rendered-value.html). Identifier.value is to be treated as case sensitive unless knowledge of the Identifier.system allows the processer to be confident that non-case-sensitive processing is safe.",
+      "min" : 1,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.value",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "string"
+      }],
+      "example" : [{
+        "label" : "General",
+        "valueString" : "123456"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.1 / EI.1"
+      },
+      {
+        "identity" : "rim",
+        "map" : "II.extension or II.root if system indicates OID or GUID (Or Role.id.extension or root)"
+      },
+      {
+        "identity" : "servd",
+        "map" : "./Value"
+      }]
+    },
+    {
+      "id" : "Identifier.period",
+      "path" : "Identifier.period",
+      "short" : "Time period when id is/was valid for use",
+      "definition" : "Time period during which identifier is/was valid for use.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.period",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "Period"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.7 + CX.8"
+      },
+      {
+        "identity" : "rim",
+        "map" : "Role.effectiveTime or implied by context"
+      },
+      {
+        "identity" : "servd",
+        "map" : "./StartDate and ./EndDate"
+      }]
+    },
+    {
+      "id" : "Identifier.assigner",
+      "path" : "Identifier.assigner",
+      "short" : "Organization that issued id (may be just text)",
+      "definition" : "Organization that issued/manages the identifier.",
+      "comment" : "The Identifier.assigner may omit the .reference element and only contain a .display element reflecting the name or other textual information about the assigning organization.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.assigner",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "Reference",
+        "targetProfile" : ["http://hl7.org/fhir/StructureDefinition/Organization"]
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.4 / (CX.4,CX.9,CX.10)"
+      },
+      {
+        "identity" : "rim",
+        "map" : "II.assigningAuthorityName but note that this is an improper use by the definition of the field.  Also Role.scoper"
+      },
+      {
+        "identity" : "servd",
+        "map" : "./IdentifierIssuingAuthority"
+      }]
+    }]
+  },
+  "differential" : {
+    "element" : [{
+      "id" : "Identifier",
+      "path" : "Identifier"
+    },
+    {
+      "id" : "Identifier.system",
+      "path" : "Identifier.system",
+      "min" : 1
+    }]
+  }
+}
\ No newline at end of file
diff --git a/test/testhelpers/testdefs/r4-definitions/package/StructureDefinition-required-type-identifier.json b/test/testhelpers/testdefs/r4-definitions/package/StructureDefinition-required-type-identifier.json
new file mode 100644
index 0000000..b61f355
--- /dev/null
+++ b/test/testhelpers/testdefs/r4-definitions/package/StructureDefinition-required-type-identifier.json
@@ -0,0 +1,432 @@
+{
+  "resourceType" : "StructureDefinition",
+  "id" : "required-type-identifier",
+  "text" : {
+    "status" : "extensions",
+    "div" : "<div xmlns=\"http://www.w3.org/1999/xhtml\"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" style=\"border: 0px #F0F0F0 solid; font-size: 11px; font-family: verdana; vertical-align: top;\"><tr style=\"border: 1px #F0F0F0 solid; font-size: 11px; font-family: verdana; vertical-align: top\"><th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"The logical name of the element\">Name</a></th><th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Information about the use of the element\">Flags</a></th><th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Minimum and Maximum # of times the the element can appear in the instance\">Card.</a></th><th style=\"width: 100px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Reference to the type of the element\">Type</a></th><th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Additional information about the element\">Description &amp; Constraints</a><span style=\"float: right\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Legend for this format\"><img src=\"http://hl7.org/fhir/R4/help16.png\" alt=\"doco\" style=\"background-color: inherit\"/></a></span></th></tr><tr style=\"border: 0px #F0F0F0 solid; padding:0px; vertical-align: top; background-color: white\"><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px; white-space: nowrap; background-image: url(tbl_bck1.png)\" class=\"hierarchy\"><img src=\"tbl_spacer.png\" alt=\".\" style=\"background-color: inherit\" class=\"hierarchy\"/><img src=\"icon_element.gif\" alt=\".\" style=\"background-color: white; background-color: inherit\" title=\"Element\" class=\"hierarchy\"/> <a href=\"StructureDefinition-required-type-identifier-definitions.html#Identifier\">Identifier</a><a name=\"Identifier\"> </a></td><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"/><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><span style=\"opacity: 0.5\">0</span><span style=\"opacity: 0.5\">..</span><span style=\"opacity: 0.5\">*</span></td><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"http://hl7.org/fhir/R4/datatypes.html#Identifier\">Identifier</a></td><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><span style=\"opacity: 0.5\">An identifier intended for computation</span></td></tr>\r\n<tr style=\"border: 0px #F0F0F0 solid; padding:0px; vertical-align: top; background-color: #F7F7F7\"><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px; white-space: nowrap; background-image: url(tbl_bck00.png)\" class=\"hierarchy\"><img src=\"tbl_spacer.png\" alt=\".\" style=\"background-color: inherit\" class=\"hierarchy\"/><img src=\"tbl_vjoin_end.png\" alt=\".\" style=\"background-color: inherit\" class=\"hierarchy\"/><img src=\"icon_element.gif\" alt=\".\" style=\"background-color: #F7F7F7; background-color: inherit\" title=\"Element\" class=\"hierarchy\"/> <a href=\"StructureDefinition-required-type-identifier-definitions.html#Identifier.type\">type</a><a name=\"Identifier.type\"> </a></td><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"/><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\">1..<span style=\"opacity: 0.5\">1</span></td><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a style=\"opacity: 0.5\" href=\"http://hl7.org/fhir/R4/datatypes.html#CodeableConcept\">CodeableConcept</a></td><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><span style=\"opacity: 0.5\">Description of identifier</span></td></tr>\r\n<tr><td colspan=\"5\" class=\"hierarchy\"><br/><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Legend for this format\"><img src=\"http://hl7.org/fhir/R4/help16.png\" alt=\"doco\" style=\"background-color: inherit\"/> Documentation for this format</a></td></tr></table></div>"
+  },
+  "url" : "http://example.org/identifiers/StructureDefinition/required-type-identifier",
+  "version" : "0.1.0",
+  "name" : "RequiredTypeIdentifier",
+  "title" : "Required Type Identifier",
+  "status" : "active",
+  "date" : "2023-03-20T12:26:54-04:00",
+  "publisher" : "Example Publisher",
+  "contact" : [{
+    "name" : "Example Publisher",
+    "telecom" : [{
+      "system" : "url",
+      "value" : "http://example.org/example-publisher"
+    }]
+  }],
+  "description" : "An identifier profile that requires the type element.",
+  "fhirVersion" : "4.0.1",
+  "mapping" : [{
+    "identity" : "v2",
+    "uri" : "http://hl7.org/v2",
+    "name" : "HL7 v2 Mapping"
+  },
+  {
+    "identity" : "rim",
+    "uri" : "http://hl7.org/v3",
+    "name" : "RIM Mapping"
+  },
+  {
+    "identity" : "servd",
+    "uri" : "http://www.omg.org/spec/ServD/1.0/",
+    "name" : "ServD"
+  }],
+  "kind" : "complex-type",
+  "abstract" : false,
+  "type" : "Identifier",
+  "baseDefinition" : "http://hl7.org/fhir/StructureDefinition/Identifier",
+  "derivation" : "constraint",
+  "snapshot" : {
+    "element" : [{
+      "id" : "Identifier",
+      "path" : "Identifier",
+      "short" : "An identifier intended for computation",
+      "definition" : "An identifier - identifies some entity uniquely and unambiguously. Typically this is used for business identifiers.",
+      "min" : 0,
+      "max" : "*",
+      "base" : {
+        "path" : "Identifier",
+        "min" : 0,
+        "max" : "*"
+      },
+      "condition" : ["ele-1"],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "mapping" : [{
+        "identity" : "rim",
+        "map" : "n/a"
+      },
+      {
+        "identity" : "v2",
+        "map" : "CX / EI (occasionally, more often EI maps to a resource id or a URL)"
+      },
+      {
+        "identity" : "rim",
+        "map" : "II - The Identifier class is a little looser than the v3 type II because it allows URIs as well as registered OIDs or GUIDs.  Also maps to Role[classCode=IDENT]"
+      },
+      {
+        "identity" : "servd",
+        "map" : "Identifier"
+      }]
+    },
+    {
+      "id" : "Identifier.id",
+      "path" : "Identifier.id",
+      "representation" : ["xmlAttr"],
+      "short" : "Unique id for inter-element referencing",
+      "definition" : "Unique id for the element within a resource (for internal references). This may be any string value that does not contain spaces.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Element.id",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "extension" : [{
+          "url" : "http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type",
+          "valueUrl" : "string"
+        }],
+        "code" : "http://hl7.org/fhirpath/System.String"
+      }],
+      "isModifier" : false,
+      "isSummary" : false,
+      "mapping" : [{
+        "identity" : "rim",
+        "map" : "n/a"
+      }]
+    },
+    {
+      "id" : "Identifier.extension",
+      "path" : "Identifier.extension",
+      "slicing" : {
+        "discriminator" : [{
+          "type" : "value",
+          "path" : "url"
+        }],
+        "description" : "Extensions are always sliced by (at least) url",
+        "rules" : "open"
+      },
+      "short" : "Additional content defined by implementations",
+      "definition" : "May be used to represent additional information that is not part of the basic definition of the element. To make the use of extensions safe and manageable, there is a strict set of governance  applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension.",
+      "comment" : "There can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions.  The use of extensions is what allows the FHIR specification to retain a core level of simplicity for everyone.",
+      "alias" : ["extensions",
+      "user content"],
+      "min" : 0,
+      "max" : "*",
+      "base" : {
+        "path" : "Element.extension",
+        "min" : 0,
+        "max" : "*"
+      },
+      "type" : [{
+        "code" : "Extension"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      },
+      {
+        "key" : "ext-1",
+        "severity" : "error",
+        "human" : "Must have either extensions or value[x], not both",
+        "expression" : "extension.exists() != value.exists()",
+        "xpath" : "exists(f:extension)!=exists(f:*[starts-with(local-name(.), \"value\")])",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Extension"
+      }],
+      "isModifier" : false,
+      "isSummary" : false,
+      "mapping" : [{
+        "identity" : "rim",
+        "map" : "n/a"
+      }]
+    },
+    {
+      "id" : "Identifier.use",
+      "path" : "Identifier.use",
+      "short" : "usual | official | temp | secondary | old (If known)",
+      "definition" : "The purpose of this identifier.",
+      "comment" : "Applications can assume that an identifier is permanent unless it explicitly says that it is temporary.",
+      "requirements" : "Allows the appropriate identifier for a particular context of use to be selected from among a set of identifiers.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.use",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "code"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : true,
+      "isModifierReason" : "This is labeled as \"Is Modifier\" because applications should not mistake a temporary id for a permanent one.",
+      "isSummary" : true,
+      "binding" : {
+        "extension" : [{
+          "url" : "http://hl7.org/fhir/StructureDefinition/elementdefinition-bindingName",
+          "valueString" : "IdentifierUse"
+        }],
+        "strength" : "required",
+        "description" : "Identifies the purpose for this identifier, if known .",
+        "valueSet" : "http://hl7.org/fhir/ValueSet/identifier-use|4.0.1"
+      },
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "N/A"
+      },
+      {
+        "identity" : "rim",
+        "map" : "Role.code or implied by context"
+      }]
+    },
+    {
+      "id" : "Identifier.type",
+      "path" : "Identifier.type",
+      "short" : "Description of identifier",
+      "definition" : "A coded type for the identifier that can be used to determine which identifier to use for a specific purpose.",
+      "comment" : "This element deals only with general categories of identifiers.  It SHOULD not be used for codes that correspond 1..1 with the Identifier.system. Some identifiers may fall into multiple categories due to common usage.   Where the system is known, a type is unnecessary because the type is always part of the system definition. However systems often need to handle identifiers where the system is not known. There is not a 1:1 relationship between type and system, since many different systems have the same type.",
+      "requirements" : "Allows users to make use of identifiers when the identifier system is not known.",
+      "min" : 1,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.type",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "CodeableConcept"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "binding" : {
+        "extension" : [{
+          "url" : "http://hl7.org/fhir/StructureDefinition/elementdefinition-bindingName",
+          "valueString" : "IdentifierType"
+        },
+        {
+          "url" : "http://hl7.org/fhir/StructureDefinition/elementdefinition-isCommonBinding",
+          "valueBoolean" : true
+        }],
+        "strength" : "extensible",
+        "description" : "A coded type for an identifier that can be used to determine which identifier to use for a specific purpose.",
+        "valueSet" : "http://hl7.org/fhir/ValueSet/identifier-type"
+      },
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.5"
+      },
+      {
+        "identity" : "rim",
+        "map" : "Role.code or implied by context"
+      }]
+    },
+    {
+      "id" : "Identifier.system",
+      "path" : "Identifier.system",
+      "short" : "The namespace for the identifier value",
+      "definition" : "Establishes the namespace for the value - that is, a URL that describes a set values that are unique.",
+      "comment" : "Identifier.system is always case sensitive.",
+      "requirements" : "There are many sets  of identifiers.  To perform matching of two identifiers, we need to know what set we're dealing with. The system identifies a particular set of unique identifiers.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.system",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "uri"
+      }],
+      "example" : [{
+        "label" : "General",
+        "valueUri" : "http://www.acme.com/identifiers/patient"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.4 / EI-2-4"
+      },
+      {
+        "identity" : "rim",
+        "map" : "II.root or Role.id.root"
+      },
+      {
+        "identity" : "servd",
+        "map" : "./IdentifierType"
+      }]
+    },
+    {
+      "id" : "Identifier.value",
+      "path" : "Identifier.value",
+      "short" : "The value that is unique",
+      "definition" : "The portion of the identifier typically relevant to the user and which is unique within the context of the system.",
+      "comment" : "If the value is a full URI, then the system SHALL be urn:ietf:rfc:3986.  The value's primary purpose is computational mapping.  As a result, it may be normalized for comparison purposes (e.g. removing non-significant whitespace, dashes, etc.)  A value formatted for human display can be conveyed using the [Rendered Value extension](http://hl7.org/fhir/R4/extension-rendered-value.html). Identifier.value is to be treated as case sensitive unless knowledge of the Identifier.system allows the processer to be confident that non-case-sensitive processing is safe.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.value",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "string"
+      }],
+      "example" : [{
+        "label" : "General",
+        "valueString" : "123456"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.1 / EI.1"
+      },
+      {
+        "identity" : "rim",
+        "map" : "II.extension or II.root if system indicates OID or GUID (Or Role.id.extension or root)"
+      },
+      {
+        "identity" : "servd",
+        "map" : "./Value"
+      }]
+    },
+    {
+      "id" : "Identifier.period",
+      "path" : "Identifier.period",
+      "short" : "Time period when id is/was valid for use",
+      "definition" : "Time period during which identifier is/was valid for use.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.period",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "Period"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.7 + CX.8"
+      },
+      {
+        "identity" : "rim",
+        "map" : "Role.effectiveTime or implied by context"
+      },
+      {
+        "identity" : "servd",
+        "map" : "./StartDate and ./EndDate"
+      }]
+    },
+    {
+      "id" : "Identifier.assigner",
+      "path" : "Identifier.assigner",
+      "short" : "Organization that issued id (may be just text)",
+      "definition" : "Organization that issued/manages the identifier.",
+      "comment" : "The Identifier.assigner may omit the .reference element and only contain a .display element reflecting the name or other textual information about the assigning organization.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.assigner",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "Reference",
+        "targetProfile" : ["http://hl7.org/fhir/StructureDefinition/Organization"]
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.4 / (CX.4,CX.9,CX.10)"
+      },
+      {
+        "identity" : "rim",
+        "map" : "II.assigningAuthorityName but note that this is an improper use by the definition of the field.  Also Role.scoper"
+      },
+      {
+        "identity" : "servd",
+        "map" : "./IdentifierIssuingAuthority"
+      }]
+    }]
+  },
+  "differential" : {
+    "element" : [{
+      "id" : "Identifier",
+      "path" : "Identifier"
+    },
+    {
+      "id" : "Identifier.type",
+      "path" : "Identifier.type",
+      "min" : 1
+    }]
+  }
+}
\ No newline at end of file
diff --git a/test/testhelpers/testdefs/r4-definitions/package/StructureDefinition-required-type-value-identifier.json b/test/testhelpers/testdefs/r4-definitions/package/StructureDefinition-required-type-value-identifier.json
new file mode 100644
index 0000000..4f57aff
--- /dev/null
+++ b/test/testhelpers/testdefs/r4-definitions/package/StructureDefinition-required-type-value-identifier.json
@@ -0,0 +1,432 @@
+{
+  "resourceType" : "StructureDefinition",
+  "id" : "required-type-value-identifier",
+  "text" : {
+    "status" : "extensions",
+    "div" : "<div xmlns=\"http://www.w3.org/1999/xhtml\"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" style=\"border: 0px #F0F0F0 solid; font-size: 11px; font-family: verdana; vertical-align: top;\"><tr style=\"border: 1px #F0F0F0 solid; font-size: 11px; font-family: verdana; vertical-align: top\"><th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"The logical name of the element\">Name</a></th><th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Information about the use of the element\">Flags</a></th><th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Minimum and Maximum # of times the the element can appear in the instance\">Card.</a></th><th style=\"width: 100px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Reference to the type of the element\">Type</a></th><th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Additional information about the element\">Description &amp; Constraints</a><span style=\"float: right\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Legend for this format\"><img src=\"http://hl7.org/fhir/R4/help16.png\" alt=\"doco\" style=\"background-color: inherit\"/></a></span></th></tr><tr style=\"border: 0px #F0F0F0 solid; padding:0px; vertical-align: top; background-color: white\"><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px; white-space: nowrap; background-image: url(tbl_bck1.png)\" class=\"hierarchy\"><img src=\"tbl_spacer.png\" alt=\".\" style=\"background-color: inherit\" class=\"hierarchy\"/><img src=\"icon_element.gif\" alt=\".\" style=\"background-color: white; background-color: inherit\" title=\"Element\" class=\"hierarchy\"/> <a href=\"StructureDefinition-required-type-value-identifier-definitions.html#Identifier\">Identifier</a><a name=\"Identifier\"> </a></td><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"/><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><span style=\"opacity: 0.5\">0</span><span style=\"opacity: 0.5\">..</span><span style=\"opacity: 0.5\">*</span></td><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"StructureDefinition-required-value-identifier.html\">RequiredValueIdentifier</a></td><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><span style=\"opacity: 0.5\">An identifier intended for computation</span></td></tr>\r\n<tr style=\"border: 0px #F0F0F0 solid; padding:0px; vertical-align: top; background-color: #F7F7F7\"><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px; white-space: nowrap; background-image: url(tbl_bck00.png)\" class=\"hierarchy\"><img src=\"tbl_spacer.png\" alt=\".\" style=\"background-color: inherit\" class=\"hierarchy\"/><img src=\"tbl_vjoin_end.png\" alt=\".\" style=\"background-color: inherit\" class=\"hierarchy\"/><img src=\"icon_element.gif\" alt=\".\" style=\"background-color: #F7F7F7; background-color: inherit\" title=\"Element\" class=\"hierarchy\"/> <a href=\"StructureDefinition-required-type-value-identifier-definitions.html#Identifier.type\">type</a><a name=\"Identifier.type\"> </a></td><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"/><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\">1..<span style=\"opacity: 0.5\">1</span></td><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a style=\"opacity: 0.5\" href=\"http://hl7.org/fhir/R4/datatypes.html#CodeableConcept\">CodeableConcept</a></td><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><span style=\"opacity: 0.5\">Description of identifier</span></td></tr>\r\n<tr><td colspan=\"5\" class=\"hierarchy\"><br/><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Legend for this format\"><img src=\"http://hl7.org/fhir/R4/help16.png\" alt=\"doco\" style=\"background-color: inherit\"/> Documentation for this format</a></td></tr></table></div>"
+  },
+  "url" : "http://example.org/identifiers/StructureDefinition/required-type-value-identifier",
+  "version" : "0.1.0",
+  "name" : "RequiredTypeValueIdentifier",
+  "title" : "Required Type and Value Identifier",
+  "status" : "active",
+  "date" : "2023-03-20T12:26:54-04:00",
+  "publisher" : "Example Publisher",
+  "contact" : [{
+    "name" : "Example Publisher",
+    "telecom" : [{
+      "system" : "url",
+      "value" : "http://example.org/example-publisher"
+    }]
+  }],
+  "description" : "An identifier profile that requires the type and value elements.",
+  "fhirVersion" : "4.0.1",
+  "mapping" : [{
+    "identity" : "v2",
+    "uri" : "http://hl7.org/v2",
+    "name" : "HL7 v2 Mapping"
+  },
+  {
+    "identity" : "rim",
+    "uri" : "http://hl7.org/v3",
+    "name" : "RIM Mapping"
+  },
+  {
+    "identity" : "servd",
+    "uri" : "http://www.omg.org/spec/ServD/1.0/",
+    "name" : "ServD"
+  }],
+  "kind" : "complex-type",
+  "abstract" : false,
+  "type" : "Identifier",
+  "baseDefinition" : "http://example.org/identifiers/StructureDefinition/required-value-identifier",
+  "derivation" : "constraint",
+  "snapshot" : {
+    "element" : [{
+      "id" : "Identifier",
+      "path" : "Identifier",
+      "short" : "An identifier intended for computation",
+      "definition" : "An identifier - identifies some entity uniquely and unambiguously. Typically this is used for business identifiers.",
+      "min" : 0,
+      "max" : "*",
+      "base" : {
+        "path" : "Identifier",
+        "min" : 0,
+        "max" : "*"
+      },
+      "condition" : ["ele-1"],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "mapping" : [{
+        "identity" : "rim",
+        "map" : "n/a"
+      },
+      {
+        "identity" : "v2",
+        "map" : "CX / EI (occasionally, more often EI maps to a resource id or a URL)"
+      },
+      {
+        "identity" : "rim",
+        "map" : "II - The Identifier class is a little looser than the v3 type II because it allows URIs as well as registered OIDs or GUIDs.  Also maps to Role[classCode=IDENT]"
+      },
+      {
+        "identity" : "servd",
+        "map" : "Identifier"
+      }]
+    },
+    {
+      "id" : "Identifier.id",
+      "path" : "Identifier.id",
+      "representation" : ["xmlAttr"],
+      "short" : "Unique id for inter-element referencing",
+      "definition" : "Unique id for the element within a resource (for internal references). This may be any string value that does not contain spaces.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Element.id",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "extension" : [{
+          "url" : "http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type",
+          "valueUrl" : "string"
+        }],
+        "code" : "http://hl7.org/fhirpath/System.String"
+      }],
+      "isModifier" : false,
+      "isSummary" : false,
+      "mapping" : [{
+        "identity" : "rim",
+        "map" : "n/a"
+      }]
+    },
+    {
+      "id" : "Identifier.extension",
+      "path" : "Identifier.extension",
+      "slicing" : {
+        "discriminator" : [{
+          "type" : "value",
+          "path" : "url"
+        }],
+        "description" : "Extensions are always sliced by (at least) url",
+        "rules" : "open"
+      },
+      "short" : "Additional content defined by implementations",
+      "definition" : "May be used to represent additional information that is not part of the basic definition of the element. To make the use of extensions safe and manageable, there is a strict set of governance  applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension.",
+      "comment" : "There can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions.  The use of extensions is what allows the FHIR specification to retain a core level of simplicity for everyone.",
+      "alias" : ["extensions",
+      "user content"],
+      "min" : 0,
+      "max" : "*",
+      "base" : {
+        "path" : "Element.extension",
+        "min" : 0,
+        "max" : "*"
+      },
+      "type" : [{
+        "code" : "Extension"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      },
+      {
+        "key" : "ext-1",
+        "severity" : "error",
+        "human" : "Must have either extensions or value[x], not both",
+        "expression" : "extension.exists() != value.exists()",
+        "xpath" : "exists(f:extension)!=exists(f:*[starts-with(local-name(.), \"value\")])",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Extension"
+      }],
+      "isModifier" : false,
+      "isSummary" : false,
+      "mapping" : [{
+        "identity" : "rim",
+        "map" : "n/a"
+      }]
+    },
+    {
+      "id" : "Identifier.use",
+      "path" : "Identifier.use",
+      "short" : "usual | official | temp | secondary | old (If known)",
+      "definition" : "The purpose of this identifier.",
+      "comment" : "Applications can assume that an identifier is permanent unless it explicitly says that it is temporary.",
+      "requirements" : "Allows the appropriate identifier for a particular context of use to be selected from among a set of identifiers.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.use",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "code"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : true,
+      "isModifierReason" : "This is labeled as \"Is Modifier\" because applications should not mistake a temporary id for a permanent one.",
+      "isSummary" : true,
+      "binding" : {
+        "extension" : [{
+          "url" : "http://hl7.org/fhir/StructureDefinition/elementdefinition-bindingName",
+          "valueString" : "IdentifierUse"
+        }],
+        "strength" : "required",
+        "description" : "Identifies the purpose for this identifier, if known .",
+        "valueSet" : "http://hl7.org/fhir/ValueSet/identifier-use|4.0.1"
+      },
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "N/A"
+      },
+      {
+        "identity" : "rim",
+        "map" : "Role.code or implied by context"
+      }]
+    },
+    {
+      "id" : "Identifier.type",
+      "path" : "Identifier.type",
+      "short" : "Description of identifier",
+      "definition" : "A coded type for the identifier that can be used to determine which identifier to use for a specific purpose.",
+      "comment" : "This element deals only with general categories of identifiers.  It SHOULD not be used for codes that correspond 1..1 with the Identifier.system. Some identifiers may fall into multiple categories due to common usage.   Where the system is known, a type is unnecessary because the type is always part of the system definition. However systems often need to handle identifiers where the system is not known. There is not a 1:1 relationship between type and system, since many different systems have the same type.",
+      "requirements" : "Allows users to make use of identifiers when the identifier system is not known.",
+      "min" : 1,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.type",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "CodeableConcept"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "binding" : {
+        "extension" : [{
+          "url" : "http://hl7.org/fhir/StructureDefinition/elementdefinition-bindingName",
+          "valueString" : "IdentifierType"
+        },
+        {
+          "url" : "http://hl7.org/fhir/StructureDefinition/elementdefinition-isCommonBinding",
+          "valueBoolean" : true
+        }],
+        "strength" : "extensible",
+        "description" : "A coded type for an identifier that can be used to determine which identifier to use for a specific purpose.",
+        "valueSet" : "http://hl7.org/fhir/ValueSet/identifier-type"
+      },
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.5"
+      },
+      {
+        "identity" : "rim",
+        "map" : "Role.code or implied by context"
+      }]
+    },
+    {
+      "id" : "Identifier.system",
+      "path" : "Identifier.system",
+      "short" : "The namespace for the identifier value",
+      "definition" : "Establishes the namespace for the value - that is, a URL that describes a set values that are unique.",
+      "comment" : "Identifier.system is always case sensitive.",
+      "requirements" : "There are many sets  of identifiers.  To perform matching of two identifiers, we need to know what set we're dealing with. The system identifies a particular set of unique identifiers.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.system",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "uri"
+      }],
+      "example" : [{
+        "label" : "General",
+        "valueUri" : "http://www.acme.com/identifiers/patient"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.4 / EI-2-4"
+      },
+      {
+        "identity" : "rim",
+        "map" : "II.root or Role.id.root"
+      },
+      {
+        "identity" : "servd",
+        "map" : "./IdentifierType"
+      }]
+    },
+    {
+      "id" : "Identifier.value",
+      "path" : "Identifier.value",
+      "short" : "The value that is unique",
+      "definition" : "The portion of the identifier typically relevant to the user and which is unique within the context of the system.",
+      "comment" : "If the value is a full URI, then the system SHALL be urn:ietf:rfc:3986.  The value's primary purpose is computational mapping.  As a result, it may be normalized for comparison purposes (e.g. removing non-significant whitespace, dashes, etc.)  A value formatted for human display can be conveyed using the [Rendered Value extension](http://hl7.org/fhir/R4/extension-rendered-value.html). Identifier.value is to be treated as case sensitive unless knowledge of the Identifier.system allows the processer to be confident that non-case-sensitive processing is safe.",
+      "min" : 1,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.value",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "string"
+      }],
+      "example" : [{
+        "label" : "General",
+        "valueString" : "123456"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.1 / EI.1"
+      },
+      {
+        "identity" : "rim",
+        "map" : "II.extension or II.root if system indicates OID or GUID (Or Role.id.extension or root)"
+      },
+      {
+        "identity" : "servd",
+        "map" : "./Value"
+      }]
+    },
+    {
+      "id" : "Identifier.period",
+      "path" : "Identifier.period",
+      "short" : "Time period when id is/was valid for use",
+      "definition" : "Time period during which identifier is/was valid for use.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.period",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "Period"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.7 + CX.8"
+      },
+      {
+        "identity" : "rim",
+        "map" : "Role.effectiveTime or implied by context"
+      },
+      {
+        "identity" : "servd",
+        "map" : "./StartDate and ./EndDate"
+      }]
+    },
+    {
+      "id" : "Identifier.assigner",
+      "path" : "Identifier.assigner",
+      "short" : "Organization that issued id (may be just text)",
+      "definition" : "Organization that issued/manages the identifier.",
+      "comment" : "The Identifier.assigner may omit the .reference element and only contain a .display element reflecting the name or other textual information about the assigning organization.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.assigner",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "Reference",
+        "targetProfile" : ["http://hl7.org/fhir/StructureDefinition/Organization"]
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.4 / (CX.4,CX.9,CX.10)"
+      },
+      {
+        "identity" : "rim",
+        "map" : "II.assigningAuthorityName but note that this is an improper use by the definition of the field.  Also Role.scoper"
+      },
+      {
+        "identity" : "servd",
+        "map" : "./IdentifierIssuingAuthority"
+      }]
+    }]
+  },
+  "differential" : {
+    "element" : [{
+      "id" : "Identifier",
+      "path" : "Identifier"
+    },
+    {
+      "id" : "Identifier.type",
+      "path" : "Identifier.type",
+      "min" : 1
+    }]
+  }
+}
\ No newline at end of file
diff --git a/test/testhelpers/testdefs/r4-definitions/package/StructureDefinition-required-use-identifier.json b/test/testhelpers/testdefs/r4-definitions/package/StructureDefinition-required-use-identifier.json
new file mode 100644
index 0000000..6b2b164
--- /dev/null
+++ b/test/testhelpers/testdefs/r4-definitions/package/StructureDefinition-required-use-identifier.json
@@ -0,0 +1,432 @@
+{
+  "resourceType" : "StructureDefinition",
+  "id" : "required-use-identifier",
+  "text" : {
+    "status" : "extensions",
+    "div" : "<div xmlns=\"http://www.w3.org/1999/xhtml\"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" style=\"border: 0px #F0F0F0 solid; font-size: 11px; font-family: verdana; vertical-align: top;\"><tr style=\"border: 1px #F0F0F0 solid; font-size: 11px; font-family: verdana; vertical-align: top\"><th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"The logical name of the element\">Name</a></th><th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Information about the use of the element\">Flags</a></th><th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Minimum and Maximum # of times the the element can appear in the instance\">Card.</a></th><th style=\"width: 100px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Reference to the type of the element\">Type</a></th><th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Additional information about the element\">Description &amp; Constraints</a><span style=\"float: right\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Legend for this format\"><img src=\"http://hl7.org/fhir/R4/help16.png\" alt=\"doco\" style=\"background-color: inherit\"/></a></span></th></tr><tr style=\"border: 0px #F0F0F0 solid; padding:0px; vertical-align: top; background-color: white\"><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px; white-space: nowrap; background-image: url(tbl_bck1.png)\" class=\"hierarchy\"><img src=\"tbl_spacer.png\" alt=\".\" style=\"background-color: inherit\" class=\"hierarchy\"/><img src=\"icon_element.gif\" alt=\".\" style=\"background-color: white; background-color: inherit\" title=\"Element\" class=\"hierarchy\"/> <a href=\"StructureDefinition-required-use-identifier-definitions.html#Identifier\">Identifier</a><a name=\"Identifier\"> </a></td><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"/><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><span style=\"opacity: 0.5\">0</span><span style=\"opacity: 0.5\">..</span><span style=\"opacity: 0.5\">*</span></td><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"http://hl7.org/fhir/R4/datatypes.html#Identifier\">Identifier</a></td><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><span style=\"opacity: 0.5\">An identifier intended for computation</span></td></tr>\r\n<tr style=\"border: 0px #F0F0F0 solid; padding:0px; vertical-align: top; background-color: #F7F7F7\"><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px; white-space: nowrap; background-image: url(tbl_bck00.png)\" class=\"hierarchy\"><img src=\"tbl_spacer.png\" alt=\".\" style=\"background-color: inherit\" class=\"hierarchy\"/><img src=\"tbl_vjoin_end.png\" alt=\".\" style=\"background-color: inherit\" class=\"hierarchy\"/><img src=\"icon_element.gif\" alt=\".\" style=\"background-color: #F7F7F7; background-color: inherit\" title=\"Element\" class=\"hierarchy\"/> <a href=\"StructureDefinition-required-use-identifier-definitions.html#Identifier.use\">use</a><a name=\"Identifier.use\"> </a></td><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"/><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\">1..<span style=\"opacity: 0.5\">1</span></td><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a style=\"opacity: 0.5\" href=\"http://hl7.org/fhir/R4/datatypes.html#code\">code</a></td><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><span style=\"opacity: 0.5\">usual | official | temp | secondary | old (If known)</span></td></tr>\r\n<tr><td colspan=\"5\" class=\"hierarchy\"><br/><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Legend for this format\"><img src=\"http://hl7.org/fhir/R4/help16.png\" alt=\"doco\" style=\"background-color: inherit\"/> Documentation for this format</a></td></tr></table></div>"
+  },
+  "url" : "http://example.org/identifiers/StructureDefinition/required-use-identifier",
+  "version" : "0.1.0",
+  "name" : "RequiredUseIdentifier",
+  "title" : "Required Use Identifier",
+  "status" : "active",
+  "date" : "2023-03-20T12:26:54-04:00",
+  "publisher" : "Example Publisher",
+  "contact" : [{
+    "name" : "Example Publisher",
+    "telecom" : [{
+      "system" : "url",
+      "value" : "http://example.org/example-publisher"
+    }]
+  }],
+  "description" : "An identifier profile that requires the use element.",
+  "fhirVersion" : "4.0.1",
+  "mapping" : [{
+    "identity" : "v2",
+    "uri" : "http://hl7.org/v2",
+    "name" : "HL7 v2 Mapping"
+  },
+  {
+    "identity" : "rim",
+    "uri" : "http://hl7.org/v3",
+    "name" : "RIM Mapping"
+  },
+  {
+    "identity" : "servd",
+    "uri" : "http://www.omg.org/spec/ServD/1.0/",
+    "name" : "ServD"
+  }],
+  "kind" : "complex-type",
+  "abstract" : false,
+  "type" : "Identifier",
+  "baseDefinition" : "http://hl7.org/fhir/StructureDefinition/Identifier",
+  "derivation" : "constraint",
+  "snapshot" : {
+    "element" : [{
+      "id" : "Identifier",
+      "path" : "Identifier",
+      "short" : "An identifier intended for computation",
+      "definition" : "An identifier - identifies some entity uniquely and unambiguously. Typically this is used for business identifiers.",
+      "min" : 0,
+      "max" : "*",
+      "base" : {
+        "path" : "Identifier",
+        "min" : 0,
+        "max" : "*"
+      },
+      "condition" : ["ele-1"],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "mapping" : [{
+        "identity" : "rim",
+        "map" : "n/a"
+      },
+      {
+        "identity" : "v2",
+        "map" : "CX / EI (occasionally, more often EI maps to a resource id or a URL)"
+      },
+      {
+        "identity" : "rim",
+        "map" : "II - The Identifier class is a little looser than the v3 type II because it allows URIs as well as registered OIDs or GUIDs.  Also maps to Role[classCode=IDENT]"
+      },
+      {
+        "identity" : "servd",
+        "map" : "Identifier"
+      }]
+    },
+    {
+      "id" : "Identifier.id",
+      "path" : "Identifier.id",
+      "representation" : ["xmlAttr"],
+      "short" : "Unique id for inter-element referencing",
+      "definition" : "Unique id for the element within a resource (for internal references). This may be any string value that does not contain spaces.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Element.id",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "extension" : [{
+          "url" : "http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type",
+          "valueUrl" : "string"
+        }],
+        "code" : "http://hl7.org/fhirpath/System.String"
+      }],
+      "isModifier" : false,
+      "isSummary" : false,
+      "mapping" : [{
+        "identity" : "rim",
+        "map" : "n/a"
+      }]
+    },
+    {
+      "id" : "Identifier.extension",
+      "path" : "Identifier.extension",
+      "slicing" : {
+        "discriminator" : [{
+          "type" : "value",
+          "path" : "url"
+        }],
+        "description" : "Extensions are always sliced by (at least) url",
+        "rules" : "open"
+      },
+      "short" : "Additional content defined by implementations",
+      "definition" : "May be used to represent additional information that is not part of the basic definition of the element. To make the use of extensions safe and manageable, there is a strict set of governance  applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension.",
+      "comment" : "There can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions.  The use of extensions is what allows the FHIR specification to retain a core level of simplicity for everyone.",
+      "alias" : ["extensions",
+      "user content"],
+      "min" : 0,
+      "max" : "*",
+      "base" : {
+        "path" : "Element.extension",
+        "min" : 0,
+        "max" : "*"
+      },
+      "type" : [{
+        "code" : "Extension"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      },
+      {
+        "key" : "ext-1",
+        "severity" : "error",
+        "human" : "Must have either extensions or value[x], not both",
+        "expression" : "extension.exists() != value.exists()",
+        "xpath" : "exists(f:extension)!=exists(f:*[starts-with(local-name(.), \"value\")])",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Extension"
+      }],
+      "isModifier" : false,
+      "isSummary" : false,
+      "mapping" : [{
+        "identity" : "rim",
+        "map" : "n/a"
+      }]
+    },
+    {
+      "id" : "Identifier.use",
+      "path" : "Identifier.use",
+      "short" : "usual | official | temp | secondary | old (If known)",
+      "definition" : "The purpose of this identifier.",
+      "comment" : "Applications can assume that an identifier is permanent unless it explicitly says that it is temporary.",
+      "requirements" : "Allows the appropriate identifier for a particular context of use to be selected from among a set of identifiers.",
+      "min" : 1,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.use",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "code"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : true,
+      "isModifierReason" : "This is labeled as \"Is Modifier\" because applications should not mistake a temporary id for a permanent one.",
+      "isSummary" : true,
+      "binding" : {
+        "extension" : [{
+          "url" : "http://hl7.org/fhir/StructureDefinition/elementdefinition-bindingName",
+          "valueString" : "IdentifierUse"
+        }],
+        "strength" : "required",
+        "description" : "Identifies the purpose for this identifier, if known .",
+        "valueSet" : "http://hl7.org/fhir/ValueSet/identifier-use|4.0.1"
+      },
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "N/A"
+      },
+      {
+        "identity" : "rim",
+        "map" : "Role.code or implied by context"
+      }]
+    },
+    {
+      "id" : "Identifier.type",
+      "path" : "Identifier.type",
+      "short" : "Description of identifier",
+      "definition" : "A coded type for the identifier that can be used to determine which identifier to use for a specific purpose.",
+      "comment" : "This element deals only with general categories of identifiers.  It SHOULD not be used for codes that correspond 1..1 with the Identifier.system. Some identifiers may fall into multiple categories due to common usage.   Where the system is known, a type is unnecessary because the type is always part of the system definition. However systems often need to handle identifiers where the system is not known. There is not a 1:1 relationship between type and system, since many different systems have the same type.",
+      "requirements" : "Allows users to make use of identifiers when the identifier system is not known.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.type",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "CodeableConcept"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "binding" : {
+        "extension" : [{
+          "url" : "http://hl7.org/fhir/StructureDefinition/elementdefinition-bindingName",
+          "valueString" : "IdentifierType"
+        },
+        {
+          "url" : "http://hl7.org/fhir/StructureDefinition/elementdefinition-isCommonBinding",
+          "valueBoolean" : true
+        }],
+        "strength" : "extensible",
+        "description" : "A coded type for an identifier that can be used to determine which identifier to use for a specific purpose.",
+        "valueSet" : "http://hl7.org/fhir/ValueSet/identifier-type"
+      },
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.5"
+      },
+      {
+        "identity" : "rim",
+        "map" : "Role.code or implied by context"
+      }]
+    },
+    {
+      "id" : "Identifier.system",
+      "path" : "Identifier.system",
+      "short" : "The namespace for the identifier value",
+      "definition" : "Establishes the namespace for the value - that is, a URL that describes a set values that are unique.",
+      "comment" : "Identifier.system is always case sensitive.",
+      "requirements" : "There are many sets  of identifiers.  To perform matching of two identifiers, we need to know what set we're dealing with. The system identifies a particular set of unique identifiers.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.system",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "uri"
+      }],
+      "example" : [{
+        "label" : "General",
+        "valueUri" : "http://www.acme.com/identifiers/patient"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.4 / EI-2-4"
+      },
+      {
+        "identity" : "rim",
+        "map" : "II.root or Role.id.root"
+      },
+      {
+        "identity" : "servd",
+        "map" : "./IdentifierType"
+      }]
+    },
+    {
+      "id" : "Identifier.value",
+      "path" : "Identifier.value",
+      "short" : "The value that is unique",
+      "definition" : "The portion of the identifier typically relevant to the user and which is unique within the context of the system.",
+      "comment" : "If the value is a full URI, then the system SHALL be urn:ietf:rfc:3986.  The value's primary purpose is computational mapping.  As a result, it may be normalized for comparison purposes (e.g. removing non-significant whitespace, dashes, etc.)  A value formatted for human display can be conveyed using the [Rendered Value extension](http://hl7.org/fhir/R4/extension-rendered-value.html). Identifier.value is to be treated as case sensitive unless knowledge of the Identifier.system allows the processer to be confident that non-case-sensitive processing is safe.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.value",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "string"
+      }],
+      "example" : [{
+        "label" : "General",
+        "valueString" : "123456"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.1 / EI.1"
+      },
+      {
+        "identity" : "rim",
+        "map" : "II.extension or II.root if system indicates OID or GUID (Or Role.id.extension or root)"
+      },
+      {
+        "identity" : "servd",
+        "map" : "./Value"
+      }]
+    },
+    {
+      "id" : "Identifier.period",
+      "path" : "Identifier.period",
+      "short" : "Time period when id is/was valid for use",
+      "definition" : "Time period during which identifier is/was valid for use.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.period",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "Period"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.7 + CX.8"
+      },
+      {
+        "identity" : "rim",
+        "map" : "Role.effectiveTime or implied by context"
+      },
+      {
+        "identity" : "servd",
+        "map" : "./StartDate and ./EndDate"
+      }]
+    },
+    {
+      "id" : "Identifier.assigner",
+      "path" : "Identifier.assigner",
+      "short" : "Organization that issued id (may be just text)",
+      "definition" : "Organization that issued/manages the identifier.",
+      "comment" : "The Identifier.assigner may omit the .reference element and only contain a .display element reflecting the name or other textual information about the assigning organization.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.assigner",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "Reference",
+        "targetProfile" : ["http://hl7.org/fhir/StructureDefinition/Organization"]
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.4 / (CX.4,CX.9,CX.10)"
+      },
+      {
+        "identity" : "rim",
+        "map" : "II.assigningAuthorityName but note that this is an improper use by the definition of the field.  Also Role.scoper"
+      },
+      {
+        "identity" : "servd",
+        "map" : "./IdentifierIssuingAuthority"
+      }]
+    }]
+  },
+  "differential" : {
+    "element" : [{
+      "id" : "Identifier",
+      "path" : "Identifier"
+    },
+    {
+      "id" : "Identifier.use",
+      "path" : "Identifier.use",
+      "min" : 1
+    }]
+  }
+}
\ No newline at end of file
diff --git a/test/testhelpers/testdefs/r4-definitions/package/StructureDefinition-required-value-identifier.json b/test/testhelpers/testdefs/r4-definitions/package/StructureDefinition-required-value-identifier.json
new file mode 100644
index 0000000..82c65af
--- /dev/null
+++ b/test/testhelpers/testdefs/r4-definitions/package/StructureDefinition-required-value-identifier.json
@@ -0,0 +1,432 @@
+{
+  "resourceType" : "StructureDefinition",
+  "id" : "required-value-identifier",
+  "text" : {
+    "status" : "extensions",
+    "div" : "<div xmlns=\"http://www.w3.org/1999/xhtml\"><table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" style=\"border: 0px #F0F0F0 solid; font-size: 11px; font-family: verdana; vertical-align: top;\"><tr style=\"border: 1px #F0F0F0 solid; font-size: 11px; font-family: verdana; vertical-align: top\"><th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"The logical name of the element\">Name</a></th><th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Information about the use of the element\">Flags</a></th><th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Minimum and Maximum # of times the the element can appear in the instance\">Card.</a></th><th style=\"width: 100px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Reference to the type of the element\">Type</a></th><th style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Additional information about the element\">Description &amp; Constraints</a><span style=\"float: right\"><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Legend for this format\"><img src=\"http://hl7.org/fhir/R4/help16.png\" alt=\"doco\" style=\"background-color: inherit\"/></a></span></th></tr><tr style=\"border: 0px #F0F0F0 solid; padding:0px; vertical-align: top; background-color: white\"><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px; white-space: nowrap; background-image: url(tbl_bck1.png)\" class=\"hierarchy\"><img src=\"tbl_spacer.png\" alt=\".\" style=\"background-color: inherit\" class=\"hierarchy\"/><img src=\"icon_element.gif\" alt=\".\" style=\"background-color: white; background-color: inherit\" title=\"Element\" class=\"hierarchy\"/> <a href=\"StructureDefinition-required-value-identifier-definitions.html#Identifier\">Identifier</a><a name=\"Identifier\"> </a></td><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"/><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><span style=\"opacity: 0.5\">0</span><span style=\"opacity: 0.5\">..</span><span style=\"opacity: 0.5\">*</span></td><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a href=\"http://hl7.org/fhir/R4/datatypes.html#Identifier\">Identifier</a></td><td style=\"vertical-align: top; text-align : left; background-color: white; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><span style=\"opacity: 0.5\">An identifier intended for computation</span></td></tr>\r\n<tr style=\"border: 0px #F0F0F0 solid; padding:0px; vertical-align: top; background-color: #F7F7F7\"><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px; white-space: nowrap; background-image: url(tbl_bck00.png)\" class=\"hierarchy\"><img src=\"tbl_spacer.png\" alt=\".\" style=\"background-color: inherit\" class=\"hierarchy\"/><img src=\"tbl_vjoin_end.png\" alt=\".\" style=\"background-color: inherit\" class=\"hierarchy\"/><img src=\"icon_element.gif\" alt=\".\" style=\"background-color: #F7F7F7; background-color: inherit\" title=\"Element\" class=\"hierarchy\"/> <a href=\"StructureDefinition-required-value-identifier-definitions.html#Identifier.value\">value</a><a name=\"Identifier.value\"> </a></td><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"/><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\">1..<span style=\"opacity: 0.5\">1</span></td><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><a style=\"opacity: 0.5\" href=\"http://hl7.org/fhir/R4/datatypes.html#string\">string</a></td><td style=\"vertical-align: top; text-align : left; background-color: #F7F7F7; border: 0px #F0F0F0 solid; padding:0px 4px 0px 4px\" class=\"hierarchy\"><span style=\"opacity: 0.5\">The value that is unique</span></td></tr>\r\n<tr><td colspan=\"5\" class=\"hierarchy\"><br/><a href=\"https://build.fhir.org/ig/FHIR/ig-guidance/readingIgs.html#table-views\" title=\"Legend for this format\"><img src=\"http://hl7.org/fhir/R4/help16.png\" alt=\"doco\" style=\"background-color: inherit\"/> Documentation for this format</a></td></tr></table></div>"
+  },
+  "url" : "http://example.org/identifiers/StructureDefinition/required-value-identifier",
+  "version" : "0.1.0",
+  "name" : "RequiredValueIdentifier",
+  "title" : "Required Value Identifier",
+  "status" : "active",
+  "date" : "2023-03-20T12:26:54-04:00",
+  "publisher" : "Example Publisher",
+  "contact" : [{
+    "name" : "Example Publisher",
+    "telecom" : [{
+      "system" : "url",
+      "value" : "http://example.org/example-publisher"
+    }]
+  }],
+  "description" : "An identifier profile that requires the value element.",
+  "fhirVersion" : "4.0.1",
+  "mapping" : [{
+    "identity" : "v2",
+    "uri" : "http://hl7.org/v2",
+    "name" : "HL7 v2 Mapping"
+  },
+  {
+    "identity" : "rim",
+    "uri" : "http://hl7.org/v3",
+    "name" : "RIM Mapping"
+  },
+  {
+    "identity" : "servd",
+    "uri" : "http://www.omg.org/spec/ServD/1.0/",
+    "name" : "ServD"
+  }],
+  "kind" : "complex-type",
+  "abstract" : false,
+  "type" : "Identifier",
+  "baseDefinition" : "http://hl7.org/fhir/StructureDefinition/Identifier",
+  "derivation" : "constraint",
+  "snapshot" : {
+    "element" : [{
+      "id" : "Identifier",
+      "path" : "Identifier",
+      "short" : "An identifier intended for computation",
+      "definition" : "An identifier - identifies some entity uniquely and unambiguously. Typically this is used for business identifiers.",
+      "min" : 0,
+      "max" : "*",
+      "base" : {
+        "path" : "Identifier",
+        "min" : 0,
+        "max" : "*"
+      },
+      "condition" : ["ele-1"],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "mapping" : [{
+        "identity" : "rim",
+        "map" : "n/a"
+      },
+      {
+        "identity" : "v2",
+        "map" : "CX / EI (occasionally, more often EI maps to a resource id or a URL)"
+      },
+      {
+        "identity" : "rim",
+        "map" : "II - The Identifier class is a little looser than the v3 type II because it allows URIs as well as registered OIDs or GUIDs.  Also maps to Role[classCode=IDENT]"
+      },
+      {
+        "identity" : "servd",
+        "map" : "Identifier"
+      }]
+    },
+    {
+      "id" : "Identifier.id",
+      "path" : "Identifier.id",
+      "representation" : ["xmlAttr"],
+      "short" : "Unique id for inter-element referencing",
+      "definition" : "Unique id for the element within a resource (for internal references). This may be any string value that does not contain spaces.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Element.id",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "extension" : [{
+          "url" : "http://hl7.org/fhir/StructureDefinition/structuredefinition-fhir-type",
+          "valueUrl" : "string"
+        }],
+        "code" : "http://hl7.org/fhirpath/System.String"
+      }],
+      "isModifier" : false,
+      "isSummary" : false,
+      "mapping" : [{
+        "identity" : "rim",
+        "map" : "n/a"
+      }]
+    },
+    {
+      "id" : "Identifier.extension",
+      "path" : "Identifier.extension",
+      "slicing" : {
+        "discriminator" : [{
+          "type" : "value",
+          "path" : "url"
+        }],
+        "description" : "Extensions are always sliced by (at least) url",
+        "rules" : "open"
+      },
+      "short" : "Additional content defined by implementations",
+      "definition" : "May be used to represent additional information that is not part of the basic definition of the element. To make the use of extensions safe and manageable, there is a strict set of governance  applied to the definition and use of extensions. Though any implementer can define an extension, there is a set of requirements that SHALL be met as part of the definition of the extension.",
+      "comment" : "There can be no stigma associated with the use of extensions by any application, project, or standard - regardless of the institution or jurisdiction that uses or defines the extensions.  The use of extensions is what allows the FHIR specification to retain a core level of simplicity for everyone.",
+      "alias" : ["extensions",
+      "user content"],
+      "min" : 0,
+      "max" : "*",
+      "base" : {
+        "path" : "Element.extension",
+        "min" : 0,
+        "max" : "*"
+      },
+      "type" : [{
+        "code" : "Extension"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      },
+      {
+        "key" : "ext-1",
+        "severity" : "error",
+        "human" : "Must have either extensions or value[x], not both",
+        "expression" : "extension.exists() != value.exists()",
+        "xpath" : "exists(f:extension)!=exists(f:*[starts-with(local-name(.), \"value\")])",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Extension"
+      }],
+      "isModifier" : false,
+      "isSummary" : false,
+      "mapping" : [{
+        "identity" : "rim",
+        "map" : "n/a"
+      }]
+    },
+    {
+      "id" : "Identifier.use",
+      "path" : "Identifier.use",
+      "short" : "usual | official | temp | secondary | old (If known)",
+      "definition" : "The purpose of this identifier.",
+      "comment" : "Applications can assume that an identifier is permanent unless it explicitly says that it is temporary.",
+      "requirements" : "Allows the appropriate identifier for a particular context of use to be selected from among a set of identifiers.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.use",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "code"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : true,
+      "isModifierReason" : "This is labeled as \"Is Modifier\" because applications should not mistake a temporary id for a permanent one.",
+      "isSummary" : true,
+      "binding" : {
+        "extension" : [{
+          "url" : "http://hl7.org/fhir/StructureDefinition/elementdefinition-bindingName",
+          "valueString" : "IdentifierUse"
+        }],
+        "strength" : "required",
+        "description" : "Identifies the purpose for this identifier, if known .",
+        "valueSet" : "http://hl7.org/fhir/ValueSet/identifier-use|4.0.1"
+      },
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "N/A"
+      },
+      {
+        "identity" : "rim",
+        "map" : "Role.code or implied by context"
+      }]
+    },
+    {
+      "id" : "Identifier.type",
+      "path" : "Identifier.type",
+      "short" : "Description of identifier",
+      "definition" : "A coded type for the identifier that can be used to determine which identifier to use for a specific purpose.",
+      "comment" : "This element deals only with general categories of identifiers.  It SHOULD not be used for codes that correspond 1..1 with the Identifier.system. Some identifiers may fall into multiple categories due to common usage.   Where the system is known, a type is unnecessary because the type is always part of the system definition. However systems often need to handle identifiers where the system is not known. There is not a 1:1 relationship between type and system, since many different systems have the same type.",
+      "requirements" : "Allows users to make use of identifiers when the identifier system is not known.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.type",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "CodeableConcept"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "binding" : {
+        "extension" : [{
+          "url" : "http://hl7.org/fhir/StructureDefinition/elementdefinition-bindingName",
+          "valueString" : "IdentifierType"
+        },
+        {
+          "url" : "http://hl7.org/fhir/StructureDefinition/elementdefinition-isCommonBinding",
+          "valueBoolean" : true
+        }],
+        "strength" : "extensible",
+        "description" : "A coded type for an identifier that can be used to determine which identifier to use for a specific purpose.",
+        "valueSet" : "http://hl7.org/fhir/ValueSet/identifier-type"
+      },
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.5"
+      },
+      {
+        "identity" : "rim",
+        "map" : "Role.code or implied by context"
+      }]
+    },
+    {
+      "id" : "Identifier.system",
+      "path" : "Identifier.system",
+      "short" : "The namespace for the identifier value",
+      "definition" : "Establishes the namespace for the value - that is, a URL that describes a set values that are unique.",
+      "comment" : "Identifier.system is always case sensitive.",
+      "requirements" : "There are many sets  of identifiers.  To perform matching of two identifiers, we need to know what set we're dealing with. The system identifies a particular set of unique identifiers.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.system",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "uri"
+      }],
+      "example" : [{
+        "label" : "General",
+        "valueUri" : "http://www.acme.com/identifiers/patient"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.4 / EI-2-4"
+      },
+      {
+        "identity" : "rim",
+        "map" : "II.root or Role.id.root"
+      },
+      {
+        "identity" : "servd",
+        "map" : "./IdentifierType"
+      }]
+    },
+    {
+      "id" : "Identifier.value",
+      "path" : "Identifier.value",
+      "short" : "The value that is unique",
+      "definition" : "The portion of the identifier typically relevant to the user and which is unique within the context of the system.",
+      "comment" : "If the value is a full URI, then the system SHALL be urn:ietf:rfc:3986.  The value's primary purpose is computational mapping.  As a result, it may be normalized for comparison purposes (e.g. removing non-significant whitespace, dashes, etc.)  A value formatted for human display can be conveyed using the [Rendered Value extension](http://hl7.org/fhir/R4/extension-rendered-value.html). Identifier.value is to be treated as case sensitive unless knowledge of the Identifier.system allows the processer to be confident that non-case-sensitive processing is safe.",
+      "min" : 1,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.value",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "string"
+      }],
+      "example" : [{
+        "label" : "General",
+        "valueString" : "123456"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.1 / EI.1"
+      },
+      {
+        "identity" : "rim",
+        "map" : "II.extension or II.root if system indicates OID or GUID (Or Role.id.extension or root)"
+      },
+      {
+        "identity" : "servd",
+        "map" : "./Value"
+      }]
+    },
+    {
+      "id" : "Identifier.period",
+      "path" : "Identifier.period",
+      "short" : "Time period when id is/was valid for use",
+      "definition" : "Time period during which identifier is/was valid for use.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.period",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "Period"
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.7 + CX.8"
+      },
+      {
+        "identity" : "rim",
+        "map" : "Role.effectiveTime or implied by context"
+      },
+      {
+        "identity" : "servd",
+        "map" : "./StartDate and ./EndDate"
+      }]
+    },
+    {
+      "id" : "Identifier.assigner",
+      "path" : "Identifier.assigner",
+      "short" : "Organization that issued id (may be just text)",
+      "definition" : "Organization that issued/manages the identifier.",
+      "comment" : "The Identifier.assigner may omit the .reference element and only contain a .display element reflecting the name or other textual information about the assigning organization.",
+      "min" : 0,
+      "max" : "1",
+      "base" : {
+        "path" : "Identifier.assigner",
+        "min" : 0,
+        "max" : "1"
+      },
+      "type" : [{
+        "code" : "Reference",
+        "targetProfile" : ["http://hl7.org/fhir/StructureDefinition/Organization"]
+      }],
+      "constraint" : [{
+        "key" : "ele-1",
+        "severity" : "error",
+        "human" : "All FHIR elements must have a @value or children",
+        "expression" : "hasValue() or (children().count() > id.count())",
+        "xpath" : "@value|f:*|h:div",
+        "source" : "http://hl7.org/fhir/StructureDefinition/Element"
+      }],
+      "isModifier" : false,
+      "isSummary" : true,
+      "mapping" : [{
+        "identity" : "v2",
+        "map" : "CX.4 / (CX.4,CX.9,CX.10)"
+      },
+      {
+        "identity" : "rim",
+        "map" : "II.assigningAuthorityName but note that this is an improper use by the definition of the field.  Also Role.scoper"
+      },
+      {
+        "identity" : "servd",
+        "map" : "./IdentifierIssuingAuthority"
+      }]
+    }]
+  },
+  "differential" : {
+    "element" : [{
+      "id" : "Identifier",
+      "path" : "Identifier"
+    },
+    {
+      "id" : "Identifier.value",
+      "path" : "Identifier.value",
+      "min" : 1
+    }]
+  }
+}
\ No newline at end of file