Merge branch 'master' into hapi3_refactor

This commit is contained in:
James Agnew 2017-07-31 17:12:33 -04:00
commit 96543c3992
8 changed files with 637 additions and 7 deletions

View File

@ -2,6 +2,7 @@ package org.hl7.fhir.dstu3.elementmodel;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.dstu3.conformance.ProfileUtilities; import org.hl7.fhir.dstu3.conformance.ProfileUtilities;
import org.hl7.fhir.dstu3.context.IWorkerContext; import org.hl7.fhir.dstu3.context.IWorkerContext;
@ -203,7 +204,7 @@ public class Property {
ElementDefinition ed = definition; ElementDefinition ed = definition;
StructureDefinition sd = structure; StructureDefinition sd = structure;
List<ElementDefinition> children = ProfileUtilities.getChildMap(sd, ed); List<ElementDefinition> children = ProfileUtilities.getChildMap(sd, ed);
if (children.isEmpty()) { if (children.isEmpty() || isElementWithOnlyExtension(ed, children)) {
// ok, find the right definitions // ok, find the right definitions
String t = null; String t = null;
if (ed.getType().size() == 1) if (ed.getType().size() == 1)
@ -240,7 +241,13 @@ public class Property {
} }
} }
if (!"xhtml".equals(t)) { if (!"xhtml".equals(t)) {
sd = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/"+t); final String url;
if (StringUtils.isNotBlank(ed.getType().get(0).getProfile())) {
url = ed.getType().get(0).getProfile();
} else {
url = "http://hl7.org/fhir/StructureDefinition/" + t;
}
sd = context.fetchResource(StructureDefinition.class, url);
if (sd == null) if (sd == null)
throw new DefinitionException("Unable to find type '"+t+"' for name '"+elementName+"' on property "+definition.getPath()); throw new DefinitionException("Unable to find type '"+t+"' for name '"+elementName+"' on property "+definition.getPath());
children = ProfileUtilities.getChildMap(sd, sd.getSnapshot().getElement().get(0)); children = ProfileUtilities.getChildMap(sd, sd.getSnapshot().getElement().get(0));
@ -340,5 +347,18 @@ public class Property {
return context; return context;
} }
private boolean isElementWithOnlyExtension(final ElementDefinition ed, final List<ElementDefinition> children) {
boolean result = false;
if (!ed.getType().isEmpty()) {
result = true;
for (final ElementDefinition ele : children) {
if (!ele.getPath().contains("extension")) {
result = false;
break;
}
}
}
return result;
}
} }

View File

@ -23,6 +23,7 @@ import org.hl7.fhir.dstu3.elementmodel.Element.SpecialElement;
import org.hl7.fhir.dstu3.formats.FormatUtilities; import org.hl7.fhir.dstu3.formats.FormatUtilities;
import org.hl7.fhir.dstu3.formats.IParser.OutputStyle; import org.hl7.fhir.dstu3.formats.IParser.OutputStyle;
import org.hl7.fhir.dstu3.model.DateTimeType; import org.hl7.fhir.dstu3.model.DateTimeType;
import org.hl7.fhir.dstu3.model.ElementDefinition;
import org.hl7.fhir.dstu3.model.ElementDefinition.PropertyRepresentation; import org.hl7.fhir.dstu3.model.ElementDefinition.PropertyRepresentation;
import org.hl7.fhir.dstu3.model.Enumeration; import org.hl7.fhir.dstu3.model.Enumeration;
import org.hl7.fhir.dstu3.model.StructureDefinition; import org.hl7.fhir.dstu3.model.StructureDefinition;
@ -45,6 +46,7 @@ import org.w3c.dom.Document;
import org.w3c.dom.Node; import org.w3c.dom.Node;
import org.xml.sax.InputSource; import org.xml.sax.InputSource;
import org.xml.sax.XMLReader; import org.xml.sax.XMLReader;
import org.apache.commons.lang3.StringUtils;
public class XmlParser extends ParserBase { public class XmlParser extends ParserBase {
private boolean allowXsiLocation; private boolean allowXsiLocation;
@ -250,7 +252,13 @@ public class XmlParser extends ParserBase {
Node child = node.getFirstChild(); Node child = node.getFirstChild();
while (child != null) { while (child != null) {
if (child.getNodeType() == Node.ELEMENT_NODE) { if (child.getNodeType() == Node.ELEMENT_NODE) {
Property property = getElementProp(properties, child.getLocalName()); final Property property;
if (StringUtils.contains(child.getLocalName(), "extension")) {
property = getExtensionProp(properties, child);
} else {
property = getElementProp(properties, child.getLocalName());
}
if (property != null) { if (property != null) {
if (!property.isChoice() && "xhtml".equals(property.getType())) { if (!property.isChoice() && "xhtml".equals(property.getType())) {
XhtmlNode xhtml = new XhtmlParser().setValidatorMode(true).parseHtmlNode((org.w3c.dom.Element) child); XhtmlNode xhtml = new XhtmlParser().setValidatorMode(true).parseHtmlNode((org.w3c.dom.Element) child);
@ -293,6 +301,48 @@ public class XmlParser extends ParserBase {
} }
} }
private Property getExtensionProp(final List<Property> properties, final Node child) {
// get the correct property corresponding to the extension
Property property = null;
final Node extensionNode = child.getAttributes().getNamedItem("url");
if (extensionNode != null) {
for (final Property prop : properties) {
if (prop.getName().contains("extension")) {
if (findExtension(prop.getDefinition(), extensionNode.getNodeValue())) {
property = prop;
break;
}
}
}
}
if (property == null) {
property = getElementProp(properties, child.getLocalName());
}
return isDefaultExtensionElement(property) ? null : property;
}
private boolean isDefaultExtensionElement(final Property property) {
if (property == null) {
return false;
}
final ElementDefinition ed = property.getDefinition();
return StringUtils.contains(ed.getPath(), "extension") && ed.getType().isEmpty() && !ed.getSlicing().isEmpty();
}
private boolean findExtension(final ElementDefinition definition, final String localName) {
boolean result = false;
if(StringUtils.isNotBlank(localName)) {
for (ElementDefinition.TypeRefComponent type:definition.getType()) {
if(localName.equals(type.getProfile())) {
result = true;
break;
}
}
}
return result;
}
private Property getElementProp(List<Property> properties, String nodeName) { private Property getElementProp(List<Property> properties, String nodeName) {
List<Property> propsSortedByLongestFirst = new ArrayList<Property>(properties); List<Property> propsSortedByLongestFirst = new ArrayList<Property>(properties);
// sort properties according to their name longest first, so .requestOrganizationReference comes first before .request[x] // sort properties according to their name longest first, so .requestOrganizationReference comes first before .request[x]
@ -337,15 +387,34 @@ public class XmlParser extends ParserBase {
private void parseResource(String string, org.w3c.dom.Element container, Element parent, Property elementProperty) throws FHIRFormatError, DefinitionException, FHIRException, IOException { private void parseResource(String string, org.w3c.dom.Element container, Element parent, Property elementProperty) throws FHIRFormatError, DefinitionException, FHIRException, IOException {
org.w3c.dom.Element res = XMLUtil.getFirstChild(container); org.w3c.dom.Element res = XMLUtil.getFirstChild(container);
String name = res.getLocalName(); final String profile = findProfile(res);
StructureDefinition sd = context.fetchResource(StructureDefinition.class, "http://hl7.org/fhir/StructureDefinition/"+name); final StructureDefinition sd = context.fetchResource(StructureDefinition.class, profile);
if (sd == null) if (sd == null)
throw new FHIRFormatError("Contained resource does not appear to be a FHIR resource (unknown name '"+res.getLocalName()+"')"); throw new FHIRFormatError("Contained resource does not appear to be a FHIR resource (unknown name '"+res.getLocalName()+"')");
parent.updateProperty(new Property(context, sd.getSnapshot().getElement().get(0), sd), SpecialElement.fromProperty(parent.getProperty()), elementProperty); parent.updateProperty(new Property(context, sd.getSnapshot().getElement().get(0), sd), SpecialElement.fromProperty(parent.getProperty()), elementProperty);
parent.setType(name); parent.setType(res.getLocalName());
parseChildren(res.getLocalName(), res, parent); parseChildren(res.getLocalName(), res, parent);
} }
private String findProfile(final org.w3c.dom.Element res) {
String url = null;
for (int i = 0; i < res.getChildNodes().getLength(); i++) {
final Node child = res.getChildNodes().item(i);
if ("meta".equals(child.getLocalName())) {
for (int j = 0; j < child.getChildNodes().getLength(); j++) {
final Node subChild = child.getChildNodes().item(j);
if ("profile".equals(subChild.getLocalName())) {
final Node profileNode = subChild.getAttributes().getNamedItem("value");
url = profileNode.getNodeValue();
break;
}
}
break;
}
}
return StringUtils.isNotBlank(url) ? url : "http://hl7.org/fhir/StructureDefinition/" + res.getLocalName();
}
private void reapComments(org.w3c.dom.Element element, Element context) { private void reapComments(org.w3c.dom.Element element, Element context) {
Node node = element.getPreviousSibling(); Node node = element.getPreviousSibling();
while (node != null && node.getNodeType() != Node.ELEMENT_NODE) { while (node != null && node.getNodeType() != Node.ELEMENT_NODE) {

View File

@ -38,6 +38,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
private DocumentBuilderFactory myDocBuilderFactory; private DocumentBuilderFactory myDocBuilderFactory;
private StructureDefinition myStructureDefintion; private StructureDefinition myStructureDefintion;
private IValidationSupport myValidationSupport; private IValidationSupport myValidationSupport;
private boolean noTerminologyChecks = false;
/** /**
* Constructor * Constructor
@ -121,6 +122,21 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
myAnyExtensionsAllowed = theAnyExtensionsAllowed; myAnyExtensionsAllowed = theAnyExtensionsAllowed;
} }
/**
* If set to {@literal true} (default is false) the valueSet will not be validate
*/
public boolean isNoTerminologyChecks() {
return noTerminologyChecks;
}
/**
* If set to {@literal true} (default is false) the valueSet will not be validate
*/
public void setNoTerminologyChecks(final boolean theNoTerminologyChecks) {
noTerminologyChecks = theNoTerminologyChecks;
}
/** /**
* Sets the "best practice warning level". When validating, any deviations from best practices will be reported at * Sets the "best practice warning level". When validating, any deviations from best practices will be reported at
* this level. * this level.
@ -165,6 +181,7 @@ public class FhirInstanceValidator extends BaseValidatorBridge implements IValid
v.setBestPracticeWarningLevel(getBestPracticeWarningLevel()); v.setBestPracticeWarningLevel(getBestPracticeWarningLevel());
v.setAnyExtensionsAllowed(isAnyExtensionsAllowed()); v.setAnyExtensionsAllowed(isAnyExtensionsAllowed());
v.setResourceIdRule(IdStatus.OPTIONAL); v.setResourceIdRule(IdStatus.OPTIONAL);
v.setNoTerminologyChecks(isNoTerminologyChecks());
List<ValidationMessage> messages = new ArrayList<ValidationMessage>(); List<ValidationMessage> messages = new ArrayList<ValidationMessage>();

View File

@ -7,6 +7,7 @@ import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat; import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import static org.mockito.Matchers.any; import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock; import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
@ -838,6 +839,13 @@ public class FhirInstanceValidatorDstu3Test {
assertEquals(0, all.size()); assertEquals(0, all.size());
} }
@Test
public void testIsNoTerminologyChecks() {
assertFalse(myInstanceVal.isNoTerminologyChecks());
myInstanceVal.setNoTerminologyChecks(true);
assertTrue(myInstanceVal.isNoTerminologyChecks());
}
@Test @Test
@Ignore @Ignore
public void testValidateStructureDefinition() throws IOException { public void testValidateStructureDefinition() throws IOException {

View File

@ -0,0 +1,65 @@
package org.hl7.fhir.dstu3.elementmodel;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.parser.IParser;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.dstu3.hapi.validation.DefaultProfileValidationSupport;
import org.hl7.fhir.dstu3.hapi.validation.HapiWorkerContext;
import org.hl7.fhir.dstu3.model.ElementDefinition;
import org.hl7.fhir.dstu3.model.StructureDefinition;
import org.hl7.fhir.exceptions.DefinitionException;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
/**
* Created by axemj on 14/07/2017.
*/
public class PropertyTest {
private static final FhirContext ourCtx = FhirContext.forDstu3();
private Property property;
private StructureDefinition sd;
private HapiWorkerContext workerContext;
@Before
public void setUp() throws IOException {
final String sdString = IOUtils.toString(getClass().getResourceAsStream("/customPatientSd.xml"), StandardCharsets.UTF_8);
final IParser parser = ourCtx.newXmlParser();
sd = parser.parseResource(StructureDefinition.class, sdString);
workerContext = new HapiWorkerContext(ourCtx, new DefaultProfileValidationSupport());
}
@Test
public void getChildPropertiesPrimitiveTest() throws DefinitionException {
final ElementDefinition ed = sd.getSnapshot().getElement().get(1);
property = new Property(workerContext, ed, sd);
final List<Property> result = property.getChildProperties("id", null);
assertFalse(result.isEmpty());
assertEquals(3, result.size());
assertEquals("id.id", result.get(0).getDefinition().getPath());
}
@Test
public void getChildPropertiesOnlyExtensionElementTest() throws DefinitionException {
final ElementDefinition ed = sd.getSnapshot().getElement().get(23);
property = new Property(workerContext, ed, sd);
final List<Property> result = property.getChildProperties("birthdate", null);
assertFalse(result.isEmpty());
assertEquals(3, result.size());
assertEquals("date.id", result.get(0).getDefinition().getPath());
}
@Test(expected = Error.class)
public void getChildPropertiesErrorTest() throws DefinitionException {
final ElementDefinition ed = sd.getSnapshot().getElement().get(7);
property = new Property(workerContext, ed, sd);
property.getChildProperties("birthdate", null);
}
}

View File

@ -0,0 +1,447 @@
<StructureDefinition xmlns="http://hl7.org/fhir">
<id value="Patient"/>
<meta>
<lastUpdated value="2017-07-14T08:37:31.190+02:00"/>
</meta>
<contained>
<ValueSet xmlns="http://hl7.org/fhir">
<id value="1"/>
</ValueSet>
</contained>
<contained>
<ValueSet xmlns="http://hl7.org/fhir">
<id value="2"/>
</ValueSet>
</contained>
<contained>
<ValueSet xmlns="http://hl7.org/fhir">
<id value="3"/>
</ValueSet>
</contained>
<contained>
<ValueSet xmlns="http://hl7.org/fhir">
<id value="4"/>
</ValueSet>
</contained>
<contained>
<ValueSet xmlns="http://hl7.org/fhir">
<id value="5"/>
</ValueSet>
</contained>
<url value="http://www.myServer.com/fhir/StructureDefinition/Patient"/>
<version value="1.0"/>
<name value="Custom Patient"/>
<title value="Patient"/>
<status value="draft"/>
<experimental value="false"/>
<date value="2017-07-14T08:37:31+02:00"/>
<publisher value="Me"/>
<contact>
<name value="test"/>
<telecom>
<system value="email"/>
<value value="test@test.com"/>
<use value="work"/>
</telecom>
</contact>
<description value="Information about an individual receiving health care services"/>
<useContext>
<code>
<system value="urn:iso:std:iso:3166"/>
<code value="FR"/>
<display value="France"/>
</code>
</useContext>
<fhirVersion value="3.0.1"/>
<kind value="resource"/>
<abstract value="false"/>
<type value="Patient"/>
<baseDefinition value="http://hl7.org/fhir/StructureDefinition/patient"/>
<derivation value="constraint"/>
<snapshot>
<element>
<path value="Patient"/>
</element>
<element>
<path value="Patient.id"/>
<short value="Logical id of this artifact"/>
<definition value="The logical id of the resource, as used in the URL for the resource. Once assigned, this value never changes."/>
<min value="0"/>
<max value="1"/>
<type>
<code value="id"/>
</type>
<isSummary value="true"/>
</element>
<element>
<path value="Patient.meta"/>
<short value="Metadata about the resource"/>
<definition value="The metadata about the resource. This is content that is maintained by the infrastructure. Changes to the content may not always be associated with version changes to the resource."/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Meta"/>
</type>
<isSummary value="true"/>
</element>
<element>
<path value="Patient.text"/>
<max value="0"/>
</element>
<element>
<path value="Patient.contained"/>
<max value="0"/>
</element>
<element>
<path value="Patient.implicitRules"/>
<max value="0"/>
</element>
<element>
<path value="Patient.language"/>
<short value="Language of the resource content"/>
<definition value="The base language in which the resource is written."/>
<min value="0"/>
<max value="1"/>
<type>
<code value="code"/>
</type>
<isModifier value="false"/>
<isSummary value="false"/>
</element>
<element>
<path value="Patient.extension"/>
<slicing>
<discriminator>
<type value="value"/>
<path value="url"/>
</discriminator>
<rules value="open"/>
</slicing>
<definition value="May be used to represent additional information that is not part of the basic definition of the element."/>
</element>
<element>
<path value="Patient.extension"/>
<short value="identityReliabilityCode"/>
<definition value="The patient identity reliability code"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/identityReliabilityCode"/>
</type>
<isModifier value="false"/>
<isSummary value="true"/>
<binding>
<strength value="required"/>
<valueSetReference>
<reference value="ValueSet/IDENTITYSTATUS"/>
</valueSetReference>
</binding>
</element>
<element>
<path value="Patient.extension"/>
<short value="lunarBirthDate"/>
<definition value="The patient lunar's birth date"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/lunarBirthDate"/>
</type>
<isModifier value="false"/>
<isSummary value="false"/>
</element>
<element>
<path value="Patient.extension"/>
<short value="legalStatus"/>
<definition value="The patient legal status"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/legalStatus"/>
</type>
<isModifier value="false"/>
<isSummary value="false"/>
<binding>
<strength value="required"/>
<valueSetReference>
<reference value="ValueSet/ADT_LEGALSTATUS"/>
</valueSetReference>
</binding>
</element>
<element>
<path value="Patient.extension"/>
<short value="familyStatus"/>
<definition value="The patient family status"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/familyStatus"/>
</type>
<isModifier value="false"/>
<isSummary value="false"/>
<binding>
<strength value="required"/>
<valueSetReference>
<reference value="ValueSet/FAMILYSTATUS"/>
</valueSetReference>
</binding>
</element>
<element>
<path value="Patient.extension"/>
<short value="birthPlace"/>
<definition value="The patient birth place"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://hl7.org/fhir/StructureDefinition/birthPlace"/>
</type>
<isModifier value="false"/>
<isSummary value="false"/>
</element>
<element>
<path value="Patient.extension"/>
<short value="homeless"/>
<definition value="The patient being homeless, true if homeless"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/homeless"/>
</type>
<isModifier value="false"/>
<isSummary value="false"/>
</element>
<element>
<path value="Patient.extension"/>
<short value="phoneConsent"/>
<definition value="The patient consent on phone level"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/phoneConsent"/>
</type>
<isModifier value="false"/>
<isSummary value="false"/>
<binding>
<strength value="required"/>
<valueSetReference>
<reference value="ValueSet/ADT_CONTACT_CONSENT_MOBILE"/>
</valueSetReference>
</binding>
</element>
<element>
<path value="Patient.extension"/>
<short value="emailConsent"/>
<definition value="The patient consent on email level"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/emailConsent"/>
</type>
<isModifier value="false"/>
<isSummary value="false"/>
<binding>
<strength value="required"/>
<valueSetReference>
<reference value="ValueSet/ADT_CONTACT_CONSENT_EMAIL"/>
</valueSetReference>
</binding>
</element>
<element>
<path value="Patient.extension"/>
<short value="comments"/>
<definition value="The patient comments"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/comments"/>
</type>
<isModifier value="false"/>
<isSummary value="false"/>
</element>
<element>
<path value="Patient.extension"/>
<short value="nationality"/>
<definition value="The patient nationality"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://hl7.org/fhir/StructureDefinition/patient-nationality"/>
</type>
<isModifier value="false"/>
</element>
<element>
<path value="Patient.identifier"/>
<short value="An identifier for this patient"/>
<definition value="An identifier for this patient."/>
<min value="0"/>
<max value="*"/>
<type>
<code value="Identifier"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/Identifier"/>
</type>
<isModifier value="false"/>
<isSummary value="true"/>
</element>
<element>
<path value="Patient.active"/>
<max value="0"/>
</element>
<element>
<path value="Patient.name"/>
<short value="A name associated with the patient"/>
<definition value="A name associated with the individual."/>
<min value="0"/>
<max value="*"/>
<type>
<code value="HumanName"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/HumanName"/>
</type>
<isModifier value="false"/>
<isSummary value="true"/>
</element>
<element>
<path value="Patient.telecom"/>
<short value="A contact detail for the individual"/>
<definition value="A contact detail (e.g. a telephone number or an email address) by which the individual may be contacted."/>
<min value="0"/>
<max value="*"/>
<type>
<code value="ContactPoint"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/ContactPoint"/>
</type>
<isModifier value="false"/>
<isSummary value="true"/>
</element>
<element>
<path value="Patient.gender"/>
<short value="male | female | other | unknown"/>
<definition value="Administrative Gender - the gender that the patient is considered to have for administration and record keeping purposes."/>
<min value="0"/>
<max value="1"/>
<type>
<code value="code"/>
</type>
<isModifier value="false"/>
<isSummary value="true"/>
</element>
<element>
<path value="Patient.birthDate"/>
<short value="The date of birth for the individual"/>
<definition value="The date of birth for the individual."/>
<min value="0"/>
<max value="1"/>
<type>
<code value="date"/>
</type>
<isModifier value="false"/>
<isSummary value="true"/>
</element>
<element>
<path value="Patient.birthDate.extension"/>
<slicing>
<discriminator>
<type value="value"/>
<path value="url"/>
</discriminator>
<rules value="open"/>
</slicing>
</element>
<element>
<path value="Patient.birthDate.extension"/>
<short value="approximateBirthDate"/>
<definition value="Flag to indicate if the birthdate is approximative or not"/>
<min value="0"/>
<max value="1"/>
<type>
<code value="Extension"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/birthdate-approximative"/>
</type>
<isModifier value="false"/>
</element>
<element>
<path value="Patient.deceased[x]"/>
<short value="Indicates if the individual is deceased or not"/>
<definition value="Indicates if the individual is deceased or not."/>
<min value="0"/>
<max value="1"/>
<type>
<code value="boolean"/>
</type>
<type>
<code value="dateTime"/>
</type>
<isModifier value="true"/>
<isSummary value="true"/>
</element>
<element>
<path value="Patient.address"/>
<short value="Addresses for the individual"/>
<definition value="Addresses for the individual."/>
<min value="0"/>
<max value="*"/>
<type>
<code value="Address"/>
<profile value="http://www.myServer.com/fhir/StructureDefinition/Address"/>
</type>
<isModifier value="false"/>
<isSummary value="true"/>
</element>
<element>
<path value="Patient.maritalStatus"/>
<max value="0"/>
</element>
<element>
<path value="Patient.multipleBirth[x]"/>
<short value="Whether patient is part of a multiple birth"/>
<definition value="Indicates whether the patient is part of a multiple (bool) or indicates the actual birth order (integer)."/>
<min value="0"/>
<max value="1"/>
<type>
<code value="boolean"/>
</type>
<type>
<code value="integer"/>
</type>
<isModifier value="false"/>
<isSummary value="false"/>
</element>
<element>
<path value="Patient.photo"/>
<max value="0"/>
</element>
<element>
<path value="Patient.contact"/>
<max value="0"/>
</element>
<element>
<path value="Patient.animal"/>
<max value="0"/>
</element>
<element>
<path value="Patient.communication"/>
<max value="0"/>
</element>
<element>
<path value="Patient.generalPractitioner"/>
<max value="0"/>
</element>
<element>
<path value="Patient.managingOrganization"/>
<max value="0"/>
</element>
<element>
<path value="Patient.link"/>
<max value="0"/>
</element>
</snapshot>
</StructureDefinition>

View File

@ -236,6 +236,10 @@
were sometimes treated as positive numbers when processing the search. Thanks were sometimes treated as positive numbers when processing the search. Thanks
to Keith Boone for reporting and suggesting a fix! to Keith Boone for reporting and suggesting a fix!
</action> </action>
<action type="fix" issue="699">
Fix an unfortunate typo in the custom structures documentation. Thanks to
Jason Owen for the PR!
</action>
</release> </release>
<release version="2.5" date="2017-06-08"> <release version="2.5" date="2017-06-08">
<action type="fix"> <action type="fix">

View File

@ -12,7 +12,7 @@
<p> <p>
Typically, when working with FHIR the right way to provide your Typically, when working with FHIR the right way to provide your
own extensions is to work with existing resource types and simply own extensions is to work with existing resource types and simply
ass your own extensions and/or constrain out fields you don't add your own extensions and/or constrain out fields you don't
need. need.
</p> </p>
<p> <p>