Stream: python
Topic: listing all elements using models
Eric Haas (Jan 16 2019 at 17:36):
using the model I can easily list all the objects props using...
for i in [type]().elementProperties():
print(i)
e.g.
(ignoring my r4 hack for _elements)
for i in p.elementProperties():
print(i[0])
id
implicitRules
_implicitRules
language
_language
meta
contained
extension
modifierExtension
text
active
_active
address
birthDate
communication
contact
deceasedBoolean
_deceasedBoolean
deceasedDateTime
gender
_gender
generalPractitioner
identifier
link
managingOrganization
maritalStatus
multipleBirthBoolean
_multipleBirthBoolean
multipleBirthInteger
_multipleBirthInteger
name
photo
telecom
but I would like to know if there is a simple way to do something like...
for i in [type].[element].elementProperties():
print(i)
(Note this is desired but does not work like this!!)
for i in p.name.elementProperties():
print(i[0])
Coding
text
for j in p.name.Coding.elementProperties():
print (j[0])
code
display
text
~~~~
Eric Haas (Jan 16 2019 at 17:39):
like using namedTuple or something?
Eric Haas (Jan 16 2019 at 17:46):
(deleted)
Eric Haas (Jan 17 2019 at 05:36):
What I'm looking for is a way to list the "snapshot of element" recursing through the elements until I get to the primitives. I've done this using the bracket notation but would like to know if there is an easier way.
Eric Haas (Jan 17 2019 at 08:00):
from fhirclient.models import patient as P
def get_eps(name,o,depth=0):
print('--'*depth, name)
print('--','id') if depth == 0 else False
for i,j,k,l,m,n in o.elementProperties():
if i in ['extension','modifierExtension','assigner','id'] :
continue
if i =='contained':
print('--',i)
continue
try:
get_eps(i,k(), depth+1) if k() else print('--'*(depth+1),j)
except AttributeError:
pass
p = P.Patient()
get_eps(p.resource_type,p)
Eric Haas (Jan 17 2019 at 08:01):
gives you
Patient -- id -- implicitRules -- language -- meta ---- lastUpdated ---- profile ---- security etc... ~~~
Eric Haas (Jan 20 2019 at 17:49):
here is a more flexible version that allows you to list all elements in dot notation or snake case.
from fhirr4models import observation as O # my R4 model library which includes a fhir primitive hack
recursives = ['extension','modifierExtension','assigner']
root_ignore = ['contained','implicitRules','language','meta','extension','modifierExtension','text']
datatype_ignore = ['id','userSelected', 'version']
ignore_fhirprimitive = True
delimiter = '.'
list_notation ='[0]'
def get_eps(element,path, level = 0):
print(path)
for i,j,k,l,m,n in element.elementProperties():
if level > 0 and (i in recursives): # ignore recursive elements except for root level
continue
elif level == 0 and i in root_ignore: # ignore these root elements
continue
elif level > 0 and i in datatype_ignore: # ignore these datatype elements
continue
elif i.startswith('_') and ignore_fhirprimitive: # ignore _elements
continue
try:
get_eps(element=k(),path=f'{path}{delimiter}{i}{list_notation}' if l else f'{path}{delimiter}{i}',level = level +1)
except AttributeError:
pass
a = O.Observation()
get_eps(element=a,path=a.resource_type,level=0)
Eric Haas (Jan 20 2019 at 17:51):
will give you...
Observation Observation.id Observation.basedOn[0] Observation.basedOn[0].display Observation.basedOn[0].identifier Observation.basedOn[0].identifier.period Observation.basedOn[0].identifier.period.end Observation.basedOn[0].identifier.period.start Observation.basedOn[0].identifier.system Observation.basedOn[0].identifier.type Observation.basedOn[0].identifier.type.coding[0] Observation.basedOn[0].identifier.type.coding[0].code Observation.basedOn[0].identifier.type.coding[0].display Observation.basedOn[0].identifier.type.coding[0].system Observation.basedOn[0].identifier.type.text Observation.basedOn[0].identifier.use Observation.basedOn[0].identifier.value Observation.basedOn[0].reference ....
Geoff Low (Jan 24 2019 at 13:51):
Cool, how do you work the extensions that are on the model (eg working group, etc) versus those that are potentially available (extension-definitions.json); the way I see it the defined elements (ie Observations.extensions = []) could be 'hard-coded' with the values - you'd need to load the extension definitions to get what the class attribute should be called and multiplicity, but then instantiate it as an extension.Extension instance?
Eric Haas (Jan 24 2019 at 16:00):
I omitted the extensions since they recurse reaching a recursion limit in the script but you certainly could add them in as you describe.
Last updated: Apr 12 2022 at 19:14 UTC