Wide sweeping changes to get RI structures working in server mode

This commit is contained in:
jamesagnew 2015-07-05 17:14:15 -04:00
parent 8b65a9aedf
commit 8a86ad5e76
193 changed files with 39471 additions and 890 deletions

View File

@ -75,7 +75,7 @@ public class GenericClientExample {
// resource, the OperationOutcome response, etc. (assuming that
// any of these things were provided by the server! They may not
// always be)
IdDt id = outcome.getId();
IdDt id = (IdDt) outcome.getId();
System.out.println("Got ID: " + id.getValue());
// END SNIPPET: create
}
@ -100,7 +100,7 @@ public class GenericClientExample {
Boolean created = outcome.getCreated();
// The ID of the created, or the pre-existing resource
IdDt id = outcome.getId();
IdDt id = (IdDt) outcome.getId();
// END SNIPPET: createConditional
}
{
@ -149,7 +149,7 @@ public class GenericClientExample {
// resource, the OperationOutcome response, etc. (assuming that
// any of these things were provided by the server! They may not
// always be)
IdDt id = outcome.getId();
IdDt id = (IdDt) outcome.getId();
System.out.println("Got ID: " + id.getValue());
// END SNIPPET: update
}

View File

@ -1,4 +1,5 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
@ -10,9 +11,42 @@
<artifactId>hapi-deployable-pom</artifactId>
<packaging>pom</packaging>
<name>HAPI FHIR - Deployable Artifact Parent POM</name>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>animal-sniffer-maven-plugin</artifactId>
<executions>
<execution>
<id>check-java-api</id>
<phase>test</phase>
<goals>
<goal>check</goal>
</goals>
<configuration>
<signature>
<groupId>org.codehaus.mojo.signature
</groupId>
<artifactId>java16</artifactId>
<version>1.1</version>
</signature>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-all</artifactId>
<version>5.0.4</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>

View File

@ -20,10 +20,17 @@
<artifactId>junit</artifactId>
<version>${junit_version}</version>
</dependency>
<!-- Use an older version of SLF4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.7</version>
<version>1.6.0</version>
</dependency>
<dependency>

View File

@ -127,3 +127,5 @@ local.properties
# TeXlipse plugin
.texlipse
/target/
/target/

View File

@ -693,7 +693,9 @@ class ModelScanner {
resourceDef = new RuntimePrimitiveDatatypeDefinition(theDatatypeDefinition, theClass, isStandardType(theClass));
}
myClassToElementDefinitions.put(theClass, resourceDef);
myNameToElementDefinitions.put(resourceName, resourceDef);
if (!theDatatypeDefinition.isSpecialization()) {
myNameToElementDefinitions.put(resourceName, resourceDef);
}
return resourceName;
}

View File

@ -21,9 +21,11 @@ package ca.uhn.fhir.model.api;
*/
import java.io.InputStream;
import java.util.Date;
import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
@ -56,4 +58,6 @@ public interface IFhirVersion {
IVersionSpecificBundleFactory newBundleFactory(FhirContext theContext);
IPrimitiveType<Date> getLastUpdated(IBaseResource theResource);
}

View File

@ -30,6 +30,7 @@ import org.apache.http.client.methods.HttpGet;
import org.hl7.fhir.instance.model.api.IBaseDatatype;
import org.hl7.fhir.instance.model.api.IBaseReference;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.BaseIdentifiableElement;
@ -56,25 +57,30 @@ public abstract class BaseResourceReferenceDt extends BaseIdentifiableElement im
* Constructor
*
* @param theResource
* The loaded resource itself
* The loaded resource itself
*/
public BaseResourceReferenceDt(IResource theResource) {
myResource = theResource;
setReference(theResource.getId());
}
@Override
public abstract StringDt getDisplayElement();
public abstract IdDt getReference();
/**
* Gets the actual loaded and parsed resource instance, <b>if it is already present</b>. This method will return the resource instance only if it has previously been loaded using
* {@link #loadResource(IRestfulClient)} or it was contained within the resource containing this resource.
* Gets the actual loaded and parsed resource instance, <b>if it is already present</b>. This method will return the
* resource instance only if it has previously been loaded using {@link #loadResource(IRestfulClient)} or it was
* contained within the resource containing this resource.
*
* See the FHIR specification section on <a href="http://www.hl7.org/implement/standards/fhir/references.html#id">contained resources</a> for more information.
* See the FHIR specification section on <a
* href="http://www.hl7.org/implement/standards/fhir/references.html#id">contained resources</a> for more
* information.
*
* @see #loadResource(IRestfulClient)
*/
@Override
public IBaseResource getResource() {
return myResource;
}
@ -85,8 +91,9 @@ public abstract class BaseResourceReferenceDt extends BaseIdentifiableElement im
}
/**
* Returns the referenced resource, fetching it <b>if it has not already been loaded</b>. This method invokes the HTTP client to retrieve the resource unless it has already been loaded, or was a
* contained resource in which case it is simply returned.
* Returns the referenced resource, fetching it <b>if it has not already been loaded</b>. This method invokes the
* HTTP client to retrieve the resource unless it has already been loaded, or was a contained resource in which case
* it is simply returned.
*/
public IBaseResource loadResource(IRestfulClient theClient) throws IOException {
if (myResource != null) {
@ -116,7 +123,7 @@ public abstract class BaseResourceReferenceDt extends BaseIdentifiableElement im
IParser parser = context.newXmlParser();
Reader responseReader = BaseClient.createReaderFromResponse(response);
myResource = (IResource) parser.parseResource(responseReader);
myResource = parser.parseResource(responseReader);
} finally {
if (response instanceof CloseableHttpResponse) {
@ -129,6 +136,18 @@ public abstract class BaseResourceReferenceDt extends BaseIdentifiableElement im
public abstract BaseResourceReferenceDt setReference(IdDt theReference);
public BaseResourceReferenceDt setReference(IIdType theReference) {
if (theReference instanceof IdDt) {
setReference((IdDt) theReference);
} else if (theReference != null) {
setReference(new IdDt(theReference.getValue()));
} else {
setReference((IdDt) null);
}
return this;
}
@Override
public void setResource(IBaseResource theResource) {
myResource = theResource;
}

View File

@ -22,13 +22,15 @@ package ca.uhn.fhir.model.base.resource;
import java.util.List;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import ca.uhn.fhir.model.api.BaseIdentifiableElement;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.IResourceBlock;
import ca.uhn.fhir.model.primitive.CodeDt;
import ca.uhn.fhir.model.primitive.StringDt;
public interface BaseOperationOutcome extends IResource {
public interface BaseOperationOutcome extends IResource, IBaseOperationOutcome {
public abstract BaseIssue addIssue();

View File

@ -54,6 +54,7 @@ import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementDefinition.ChildTypeEnum;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.RuntimeChildChoiceDefinition;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.model.api.Bundle;
@ -353,6 +354,9 @@ public abstract class BaseParser implements IParser {
@Override
public Bundle parseBundle(Reader theReader) {
if (myContext.getVersion().getVersion() == FhirVersionEnum.DSTU2_HL7ORG) {
throw new IllegalStateException("Can't parse DSTU1 (Atom) bundle in HL7.org DSTU2 mode. Use parseResource(Bundle.class, foo) instead.");
}
return parseBundle(null, theReader);
}

View File

@ -25,7 +25,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import ca.uhn.fhir.model.api.IResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.rest.client.api.IBasicClient;
import ca.uhn.fhir.rest.client.api.IRestfulClient;
import ca.uhn.fhir.rest.server.IDynamicSearchResourceProvider;
@ -77,7 +78,7 @@ public @interface Search {
* </p>
*/
// NB: Read, Search (maybe others) share this annotation method, so update the javadocs everywhere
Class<? extends IResource> type() default IResource.class;
Class<? extends IBaseResource> type() default IBaseResource.class;
/**
* This is an experimental option - Use with caution

View File

@ -20,13 +20,15 @@ package ca.uhn.fhir.rest.api;
* #L%
*/
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.hl7.fhir.instance.model.api.IIdType;
import ca.uhn.fhir.model.primitive.IdDt;
public class MethodOutcome {
private IdDt myId;
private BaseOperationOutcome myOperationOutcome;
private IIdType myId;
private IBaseOperationOutcome myOperationOutcome;
private IdDt myVersionId;
private Boolean myCreated;
@ -42,7 +44,7 @@ public class MethodOutcome {
* @param theId
* The ID of the created/updated resource
*/
public MethodOutcome(IdDt theId) {
public MethodOutcome(IIdType theId) {
myId = theId;
}
@ -70,7 +72,7 @@ public class MethodOutcome {
* @param theBaseOperationOutcome
* The operation outcome to return with the response (or null for none)
*/
public MethodOutcome(IdDt theId, BaseOperationOutcome theBaseOperationOutcome) {
public MethodOutcome(IdDt theId, IBaseOperationOutcome theBaseOperationOutcome) {
myId = theId;
myOperationOutcome = theBaseOperationOutcome;
}
@ -88,7 +90,7 @@ public class MethodOutcome {
* If not null, indicates whether the resource was created (as opposed to being updated). This is generally not needed, since the server can assume based on the method being called
* whether the result was a creation or an update. However, it can be useful if you are implementing an update method that does a create if the ID doesn't already exist.
*/
public MethodOutcome(IdDt theId, BaseOperationOutcome theBaseOperationOutcome, Boolean theCreated) {
public MethodOutcome(IdDt theId, IBaseOperationOutcome theBaseOperationOutcome, Boolean theCreated) {
myId = theId;
myOperationOutcome = theBaseOperationOutcome;
myCreated = theCreated;
@ -107,22 +109,22 @@ public class MethodOutcome {
* @deprecated Use the constructor which accepts a single IdDt parameter, and include the logical ID and version ID in that IdDt instance
*/
@Deprecated
public MethodOutcome(IdDt theId, IdDt theVersionId, BaseOperationOutcome theBaseOperationOutcome) {
public MethodOutcome(IdDt theId, IdDt theVersionId, IBaseOperationOutcome theBaseOperationOutcome) {
myId = theId;
myVersionId = theVersionId;
myOperationOutcome = theBaseOperationOutcome;
}
public IdDt getId() {
public IIdType getId() {
return myId;
}
/**
* Returns the {@link BaseOperationOutcome} resource to return to the client or <code>null</code> if none.
* Returns the {@link IBaseOperationOutcome} resource to return to the client or <code>null</code> if none.
*
* @return This method <b>will return null</b>, unlike many methods in the API.
*/
public BaseOperationOutcome getOperationOutcome() {
public IBaseOperationOutcome getOperationOutcome() {
return myOperationOutcome;
}
@ -167,9 +169,9 @@ public class MethodOutcome {
}
/**
* Sets the {@link BaseOperationOutcome} resource to return to the client. Set to <code>null</code> (which is the default) if none.
* Sets the {@link IBaseOperationOutcome} resource to return to the client. Set to <code>null</code> (which is the default) if none.
*/
public void setOperationOutcome(BaseOperationOutcome theBaseOperationOutcome) {
public void setOperationOutcome(IBaseOperationOutcome theBaseOperationOutcome) {
myOperationOutcome = theBaseOperationOutcome;
}

View File

@ -216,9 +216,9 @@ public class GenericClient extends BaseClient implements IGenericClient {
return delete(theType, new IdDt(theId));
}
private <T extends IBaseResource> T doReadOrVRead(final Class<T> theType, IdDt theId, boolean theVRead, ICallable<T> theNotModifiedHandler, String theIfVersionMatches) {
private <T extends IBaseResource> T doReadOrVRead(final Class<T> theType, IIdType theId, boolean theVRead, ICallable<T> theNotModifiedHandler, String theIfVersionMatches) {
String resName = toResourceName(theType);
IdDt id = theId;
IIdType id = theId;
if (!id.hasBaseUrl()) {
id = new IdDt(resName, id.getIdPart(), id.getVersionIdPart());
}
@ -1289,7 +1289,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
@SuppressWarnings({ "rawtypes", "unchecked" })
private class ReadInternal extends BaseClientExecutable implements IRead, IReadTyped, IReadExecutable {
private IdDt myId;
private IIdType myId;
private String myIfVersionMatches;
private ICallable myNotModifiedHandler;
private RuntimeResourceDefinition myType;
@ -1370,7 +1370,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
}
@Override
public IReadExecutable withId(IdDt theId) {
public IReadExecutable withId(IIdType theId) {
Validate.notNull(theId, "The ID can not be null");
Validate.notBlank(theId.getIdPart(), "The ID can not be blank");
myId = theId.toUnqualified();
@ -1392,7 +1392,7 @@ public class GenericClient extends BaseClient implements IGenericClient {
}
@Override
public IReadExecutable withUrl(IdDt theUrl) {
public IReadExecutable withUrl(IIdType theUrl) {
Validate.notNull(theUrl, "theUrl can not be null");
myId = theUrl;
processUrl();
@ -1434,10 +1434,10 @@ public class GenericClient extends BaseClient implements IGenericClient {
private final class ResourceResponseHandler<T extends IBaseResource> implements IClientResponseHandler<T> {
private IdDt myId;
private IIdType myId;
private Class<T> myType;
public ResourceResponseHandler(Class<T> theType, IdDt theId) {
public ResourceResponseHandler(Class<T> theType, IIdType theId) {
myType = theType;
myId = theId;
}

View File

@ -382,5 +382,6 @@ public interface IGenericClient extends IRestfulClient {
*/
<T extends IBaseResource> T vread(Class<T> theType, String theId, String theVersionId);
}

View File

@ -21,8 +21,7 @@ package ca.uhn.fhir.rest.gclient;
*/
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.model.primitive.IdDt;
import org.hl7.fhir.instance.model.api.IIdType;
public interface IReadTyped<T extends IBaseResource> {
@ -34,11 +33,11 @@ public interface IReadTyped<T extends IBaseResource> {
* Search using an ID. Note that even if theId contains a base URL it will be
* ignored in favour of the base url for the given client. If you want to specify
* an absolute URL including a base and have that base used instead, use
* {@link #withUrl(IdDt)}
* {@link #withUrl(IIdType)}
*/
IReadExecutable<T> withId(IdDt theId);
IReadExecutable<T> withId(IIdType theId);
IReadExecutable<T> withUrl(String theUrl);
IReadExecutable<T> withUrl(IdDt theUrl);
IReadExecutable<T> withUrl(IIdType theUrl);
}

View File

@ -35,6 +35,7 @@ import java.util.Set;
import java.util.TreeSet;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.instance.model.api.IAnyResource;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.ConfigurationException;
@ -362,8 +363,8 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
return BundleProviders.newEmptyList();
} else if (response instanceof IBundleProvider) {
return (IBundleProvider) response;
} else if (response instanceof IResource) {
return BundleProviders.newList((IResource) response);
} else if (response instanceof IBaseResource) {
return BundleProviders.newList((IBaseResource) response);
} else if (response instanceof Collection) {
List<IBaseResource> retVal = new ArrayList<IBaseResource>();
for (Object next : ((Collection<?>) response)) {
@ -427,18 +428,18 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
// returns a bundle
} else if (Collection.class.isAssignableFrom(returnTypeFromMethod)) {
returnTypeFromMethod = ReflectionUtil.getGenericCollectionTypeOfMethodReturnType(theMethod);
if (!verifyIsValidResourceReturnType(returnTypeFromMethod) && !IResource.class.equals(returnTypeFromMethod)) {
if (!verifyIsValidResourceReturnType(returnTypeFromMethod) && !isResourceInterface(returnTypeFromMethod)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + " returns a collection with generic type " + toLogString(returnTypeFromMethod)
+ " - Must return a resource type or a collection (List, Set) with a resource type parameter (e.g. List<Patient> or List<IResource> )");
+ " - Must return a resource type or a collection (List, Set) with a resource type parameter (e.g. List<Patient> or List<IBaseResource> )");
}
} else {
if (!IResource.class.equals(returnTypeFromMethod) && !verifyIsValidResourceReturnType(returnTypeFromMethod)) {
if (!isResourceInterface(returnTypeFromMethod) && !verifyIsValidResourceReturnType(returnTypeFromMethod)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + " returns " + toLogString(returnTypeFromMethod) + " - Must return a resource type (eg Patient, "
+ Bundle.class.getSimpleName() + ", " + IBundleProvider.class.getSimpleName() + ", etc., see the documentation for more details)");
}
}
Class<? extends IResource> returnTypeFromAnnotation = IResource.class;
Class<? extends IBaseResource> returnTypeFromAnnotation = IBaseResource.class;
if (read != null) {
returnTypeFromAnnotation = read.type();
} else if (search != null) {
@ -462,7 +463,7 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
}
if (returnTypeFromRp != null) {
if (returnTypeFromAnnotation != null && returnTypeFromAnnotation != IResource.class) {
if (returnTypeFromAnnotation != null && !isResourceInterface(returnTypeFromAnnotation)) {
if (!returnTypeFromRp.isAssignableFrom(returnTypeFromAnnotation)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' in type " + theMethod.getDeclaringClass().getCanonicalName() + " returns type " + returnTypeFromMethod.getCanonicalName() + " - Must return " + returnTypeFromRp.getCanonicalName()
+ " (or a subclass of it) per IResourceProvider contract");
@ -476,7 +477,7 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
returnType = returnTypeFromRp;
}
} else {
if (returnTypeFromAnnotation != IResource.class) {
if (!isResourceInterface(returnTypeFromAnnotation)) {
if (!verifyIsValidResourceReturnType(returnTypeFromAnnotation)) {
throw new ConfigurationException("Method '" + theMethod.getName() + "' from " + IResourceProvider.class.getSimpleName() + " type " + theMethod.getDeclaringClass().getCanonicalName() + " returns " + toLogString(returnTypeFromAnnotation)
+ " according to annotation - Must return a resource type");
@ -486,7 +487,7 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
// if (IRestfulClient.class.isAssignableFrom(theMethod.getDeclaringClass())) {
// Clients don't define their methods in resource specific types, so they can
// infer their resource type from the method return type.
returnType = (Class<? extends IResource>) returnTypeFromMethod;
returnType = (Class<? extends IBaseResource>) returnTypeFromMethod;
// } else {
// This is a plain provider method returning a resource, so it should be
// an operation or global search presumably
@ -555,6 +556,10 @@ public abstract class BaseMethodBinding<T> implements IClientResponseHandler<T>
// return sm;
}
private static boolean isResourceInterface(Class<?> theReturnTypeFromMethod) {
return theReturnTypeFromMethod.equals(IBaseResource.class) || theReturnTypeFromMethod.equals(IResource.class) || theReturnTypeFromMethod.equals(IAnyResource.class);
}
private static void populateException(BaseServerResponseException theEx, Reader theResponseReader) {
try {
String responseText = IOUtils.toString(theResponseReader);

View File

@ -31,11 +31,11 @@ import java.util.Set;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.parser.IParser;
import ca.uhn.fhir.rest.api.MethodOutcome;
@ -170,7 +170,7 @@ abstract class BaseOutcomeReturningMethodBinding extends BaseMethodBinding<Metho
}
}
BaseOperationOutcome outcome = response != null ? response.getOperationOutcome() : null;
IBaseOperationOutcome outcome = response != null ? response.getOperationOutcome() : null;
for (int i = theServer.getInterceptors().size() - 1; i >= 0; i--) {
IServerInterceptor next = theServer.getInterceptors().get(i);
boolean continueProcessing = next.outgoingResponse(theRequest, outcome, theRequest.getServletRequest(), theRequest.getServletResponse());

View File

@ -24,10 +24,12 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.client.BaseHttpClientInvocation;
import ca.uhn.fhir.rest.param.ResourceParameter;
@ -39,7 +41,9 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu
private String myResourceName;
private int myResourceParameterIndex;
private Class<? extends IBaseResource> myResourceType;
private Class<? extends IIdType> myIdParamType;
@SuppressWarnings("unchecked")
public BaseOutcomeReturningMethodBindingWithResourceParam(Method theMethod, FhirContext theContext, Class<?> theMethodAnnotation, Object theProvider) {
super(theMethod, theContext, theMethodAnnotation, theProvider);
@ -72,7 +76,10 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu
myResourceName = theContext.getResourceDefinition(myResourceType).getName();
myIdParamIndex = MethodUtil.findIdParameterIndex(theMethod);
if (myIdParamIndex != null) {
myIdParamType = (Class<? extends IIdType>) theMethod.getParameterTypes()[myIdParamIndex];
}
if (resourceParameter == null) {
throw new ConfigurationException("Method " + theMethod.getName() + " in type " + theMethod.getDeclaringClass().getCanonicalName() + " does not have a resource parameter annotated with @" + ResourceParam.class.getSimpleName());
}
@ -82,10 +89,11 @@ abstract class BaseOutcomeReturningMethodBindingWithResourceParam extends BaseOu
@Override
protected void addParametersForServerRequest(RequestDetails theRequest, Object[] theParams) {
if (myIdParamIndex != null) {
theParams[myIdParamIndex] = theRequest.getId();
theParams[myIdParamIndex] = MethodUtil.convertIdToType(theRequest.getId(), myIdParamType);
}
}
@Override
public String getResourceName() {
return myResourceName;

View File

@ -29,6 +29,7 @@ import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@ -38,6 +39,7 @@ import java.util.Set;
import javax.servlet.http.HttpServletResponse;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
@ -124,17 +126,12 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
}
if (theReturnResourceType != null) {
if (IResource.class.isAssignableFrom(theReturnResourceType)) {
ResourceDef resourceDefAnnotation = theReturnResourceType.getAnnotation(ResourceDef.class);
if (resourceDefAnnotation == null) {
if (Modifier.isAbstract(theReturnResourceType.getModifiers())) {
// If we're returning an abstract type, that's ok
} else {
throw new ConfigurationException(theReturnResourceType.getCanonicalName() + " has no @" + ResourceDef.class.getSimpleName() + " annotation");
}
if (IBaseResource.class.isAssignableFrom(theReturnResourceType)) {
if (Modifier.isAbstract(theReturnResourceType.getModifiers()) || Modifier.isInterface(theReturnResourceType.getModifiers())) {
// If we're returning an abstract type, that's ok
} else {
myResourceType = (Class<? extends IResource>) theReturnResourceType;
myResourceName = resourceDefAnnotation.name();
myResourceName = theContext.getResourceDefinition(myResourceType).getName();
}
}
}
@ -309,14 +306,14 @@ abstract class BaseResourceReturningMethodBinding extends BaseMethodBinding<Obje
if (getMethodReturnType() == MethodReturnTypeEnum.BUNDLE_RESOURCE) {
IBaseResource resource;
InstantDt lastUpdated;
IPrimitiveType<Date> lastUpdated;
if (resultObj instanceof IBundleProvider) {
IBundleProvider result = (IBundleProvider) resultObj;
resource = result.getResources(0, 1).get(0);
lastUpdated = result.getPublished();
} else {
resource = (IResource) resultObj;
lastUpdated = ResourceMetadataKeyEnum.UPDATED.get((IResource) resource);
resource = (IBaseResource) resultObj;
lastUpdated = theServer.getFhirContext().getVersion().getLastUpdated(resource);
}
/*

View File

@ -22,10 +22,11 @@ package ca.uhn.fhir.rest.method;
import java.lang.reflect.Method;
import org.hl7.fhir.instance.model.api.IBaseConformance;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.base.resource.BaseConformance;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationSystemEnum;
import ca.uhn.fhir.model.dstu.valueset.RestfulOperationTypeEnum;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
@ -43,7 +44,9 @@ public class ConformanceMethodBinding extends BaseResourceReturningMethodBinding
// if (Modifier.isAbstract(theMethod.getReturnType().getModifiers())) {
// throw new ConfigurationException("Conformance resource provider method '" + theMethod.getName() + "' must not be abstract");
// }
if (getMethodReturnType() != MethodReturnTypeEnum.RESOURCE || !BaseConformance.class.isAssignableFrom((Class<?>) theMethod.getGenericReturnType())) {
MethodReturnTypeEnum methodReturnType = getMethodReturnType();
Class<?> genericReturnType = (Class<?>) theMethod.getGenericReturnType();
if (methodReturnType != MethodReturnTypeEnum.RESOURCE || !IBaseConformance.class.isAssignableFrom(genericReturnType)) {
throw new ConfigurationException("Conformance resource provider method '" + theMethod.getName() + "' should return a Conformance resource class, returns: " + theMethod.getReturnType());
}
@ -70,7 +73,7 @@ public class ConformanceMethodBinding extends BaseResourceReturningMethodBinding
@Override
public IBundleProvider invokeServer(RequestDetails theRequest, Object[] theMethodParams) throws BaseServerResponseException {
IResource conf = (IResource) invokeServerMethod(theMethodParams);
IBaseResource conf = (IBaseResource) invokeServerMethod(theMethodParams);
return new SimpleBundleProvider(conf);
}

View File

@ -110,7 +110,7 @@ public class DynamicSearchMethodBinding extends BaseResourceReturningMethodBindi
@Override
public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) {
if (!theRequest.getResourceName().equals(getResourceName())) {
ourLog.trace("Method {} doesn't match because resource name {} != {}", getMethod().getName(), theRequest.getResourceName(), getResourceName());
ourLog.trace("Method {} doesn't match because resource name {} != {}", new Object[] { getMethod().getName(), theRequest.getResourceName(), getResourceName() } );
return false;
}
if (theRequest.getId() != null && myIdParamIndex == null) {

View File

@ -127,6 +127,22 @@ public class MethodUtil {
}
}
public static IIdType convertIdToType(IIdType value, Class<? extends IIdType> idParamType) {
if (value != null && !idParamType.isAssignableFrom(value.getClass())) {
try {
IIdType newValue = idParamType.newInstance();
newValue.setValue(value.getValue());
value = newValue;
} catch (InstantiationException e) {
throw new ConfigurationException("Failed to instantiate " + idParamType, e);
} catch (IllegalAccessException e) {
throw new ConfigurationException("Failed to instantiate " + idParamType, e);
}
}
return value;
}
public static HttpGetClientInvocation createConformanceInvocation() {
return new HttpGetClientInvocation("metadata");
}
@ -181,42 +197,6 @@ public class MethodUtil {
return retVal;
}
public static HttpPutClientInvocation createUpdateInvocation(IBaseResource theResource, String theResourceBody, IIdType theId, FhirContext theContext) {
String resourceName = theContext.getResourceDefinition(theResource).getName();
StringBuilder urlBuilder = new StringBuilder();
urlBuilder.append(resourceName);
urlBuilder.append('/');
urlBuilder.append(theId.getIdPart());
String urlExtension = urlBuilder.toString();
HttpPutClientInvocation retVal;
if (StringUtils.isBlank(theResourceBody)) {
retVal = new HttpPutClientInvocation(theContext, theResource, urlExtension);
} else {
retVal = new HttpPutClientInvocation(theContext, theResourceBody, false, urlExtension);
}
if (theId.hasVersionIdPart()) {
if (theContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
retVal.addHeader(Constants.HEADER_IF_MATCH, '"' + theId.getVersionIdPart() + '"');
} else {
String versionId = theId.getVersionIdPart();
if (StringUtils.isNotBlank(versionId)) {
urlBuilder.append('/');
urlBuilder.append(Constants.PARAM_HISTORY);
urlBuilder.append('/');
urlBuilder.append(versionId);
retVal.addHeader(Constants.HEADER_CONTENT_LOCATION, urlBuilder.toString());
}
}
}
addTagsToPostOrPut(theContext, theResource, retVal);
// addContentTypeHeaderBasedOnDetectedType(retVal, theResourceBody);
return retVal;
}
public static HttpPutClientInvocation createUpdateInvocation(FhirContext theContext, IBaseResource theResource, String theResourceBody, Map<String, List<String>> theMatchParams) {
StringBuilder b = new StringBuilder();
@ -263,6 +243,42 @@ public class MethodUtil {
return retVal;
}
public static HttpPutClientInvocation createUpdateInvocation(IBaseResource theResource, String theResourceBody, IIdType theId, FhirContext theContext) {
String resourceName = theContext.getResourceDefinition(theResource).getName();
StringBuilder urlBuilder = new StringBuilder();
urlBuilder.append(resourceName);
urlBuilder.append('/');
urlBuilder.append(theId.getIdPart());
String urlExtension = urlBuilder.toString();
HttpPutClientInvocation retVal;
if (StringUtils.isBlank(theResourceBody)) {
retVal = new HttpPutClientInvocation(theContext, theResource, urlExtension);
} else {
retVal = new HttpPutClientInvocation(theContext, theResourceBody, false, urlExtension);
}
if (theId.hasVersionIdPart()) {
if (theContext.getVersion().getVersion().isNewerThan(FhirVersionEnum.DSTU1)) {
retVal.addHeader(Constants.HEADER_IF_MATCH, '"' + theId.getVersionIdPart() + '"');
} else {
String versionId = theId.getVersionIdPart();
if (StringUtils.isNotBlank(versionId)) {
urlBuilder.append('/');
urlBuilder.append(Constants.PARAM_HISTORY);
urlBuilder.append('/');
urlBuilder.append(versionId);
retVal.addHeader(Constants.HEADER_CONTENT_LOCATION, urlBuilder.toString());
}
}
}
addTagsToPostOrPut(theContext, theResource, retVal);
// addContentTypeHeaderBasedOnDetectedType(retVal, theResourceBody);
return retVal;
}
public static EncodingEnum detectEncoding(String theBody) {
EncodingEnum retVal = detectEncodingNoDefault(theBody);
if (retVal == null) {
@ -299,6 +315,10 @@ public class MethodUtil {
}
}
public static Integer findConditionalOperationParameterIndex(Method theMethod) {
return MethodUtil.findParamAnnotationIndex(theMethod, ConditionalUrlParam.class);
}
public static Integer findIdParameterIndex(Method theMethod) {
return MethodUtil.findParamAnnotationIndex(theMethod, IdParam.class);
}
@ -322,10 +342,6 @@ public class MethodUtil {
return MethodUtil.findParamAnnotationIndex(theMethod, TagListParam.class);
}
public static Integer findConditionalOperationParameterIndex(Method theMethod) {
return MethodUtil.findParamAnnotationIndex(theMethod, ConditionalUrlParam.class);
}
@SuppressWarnings("deprecation")
public static Integer findVersionIdParameterIndex(Method theMethod) {
return MethodUtil.findParamAnnotationIndex(theMethod, VersionIdParam.class);
@ -447,13 +463,13 @@ public class MethodUtil {
}
param = new OperationParameter(Constants.EXTOP_VALIDATE, Constants.EXTOP_VALIDATE_MODE, 0, 1).setConverter(new IConverter() {
@Override
public Object outgoingClient(Object theObject) {
return new StringDt(((ValidationModeEnum)theObject).name().toLowerCase());
public Object incomingServer(Object theObject) {
return ValidationModeEnum.valueOf(theObject.toString().toUpperCase());
}
@Override
public Object incomingServer(Object theObject) {
return ValidationModeEnum.valueOf(theObject.toString().toUpperCase());
public Object outgoingClient(Object theObject) {
return new StringDt(((ValidationModeEnum)theObject).name().toLowerCase());
}
});
} else if (nextAnnotation instanceof Validate.Profile) {
@ -462,13 +478,13 @@ public class MethodUtil {
}
param = new OperationParameter(Constants.EXTOP_VALIDATE, Constants.EXTOP_VALIDATE_PROFILE, 0, 1).setConverter(new IConverter() {
@Override
public Object outgoingClient(Object theObject) {
return new StringDt(theObject.toString());
public Object incomingServer(Object theObject) {
return theObject.toString();
}
@Override
public Object incomingServer(Object theObject) {
return theObject.toString();
public Object outgoingClient(Object theObject) {
return new StringDt(theObject.toString());
}
});
} else {
@ -492,7 +508,7 @@ public class MethodUtil {
return parameters;
}
public static void parseClientRequestResourceHeaders(IdDt theRequestedId, Map<String, List<String>> theHeaders, IBaseResource resource) {
public static void parseClientRequestResourceHeaders(IIdType theRequestedId, Map<String, List<String>> theHeaders, IBaseResource resource) {
List<String> lmHeaders = theHeaders.get(Constants.HEADER_LAST_MODIFIED_LOWERCASE);
if (lmHeaders != null && lmHeaders.size() > 0 && StringUtils.isNotBlank(lmHeaders.get(0))) {
String headerValue = lmHeaders.get(0);

View File

@ -33,6 +33,7 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBaseBinary;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
@ -60,7 +61,9 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
private Integer myIdIndex;
private boolean mySupportsVersion;
private Integer myVersionIdIndex;
private Class<? extends IIdType> myIdParameterType;
@SuppressWarnings("unchecked")
public ReadMethodBinding(Class<? extends IBaseResource> theAnnotatedResourceType, Method theMethod, FhirContext theContext, Object theProvider) {
super(theAnnotatedResourceType, theMethod, theContext, theProvider);
@ -69,17 +72,19 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
Integer idIndex = MethodUtil.findIdParameterIndex(theMethod);
Integer versionIdIndex = MethodUtil.findVersionIdParameterIndex(theMethod);
Class<?>[] parameterTypes = theMethod.getParameterTypes();
mySupportsVersion = theMethod.getAnnotation(Read.class).version();
myIdIndex = idIndex;
myVersionIdIndex = versionIdIndex;
if (myIdIndex== null) {
if (myIdIndex == null) {
throw new ConfigurationException("@" + Read.class.getSimpleName() + " method " + theMethod.getName() + " on type \"" + theMethod.getDeclaringClass().getName() + "\" does not have a parameter annotated with @" + IdParam.class.getSimpleName());
}
Class<?>[] parameterTypes = theMethod.getParameterTypes();
if (!IdDt.class.equals(parameterTypes[myIdIndex])) {
throw new ConfigurationException("ID parameter must be of type: " + IdDt.class.getCanonicalName() + " - Found: " + parameterTypes[myIdIndex]);
myIdParameterType = (Class<? extends IIdType>) parameterTypes[myIdIndex];
if (!IIdType.class.isAssignableFrom(myIdParameterType)) {
throw new ConfigurationException("ID parameter must be of type IdDt or IdType - Found: " + myIdParameterType);
}
if (myVersionIdIndex != null && !IdDt.class.equals(parameterTypes[myVersionIdIndex])) {
throw new ConfigurationException("Version ID parameter must be of type: " + IdDt.class.getCanonicalName() + " - Found: " + parameterTypes[myVersionIdIndex]);
@ -173,7 +178,7 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
@Override
public Object invokeClient(String theResponseMimeType, InputStream theResponseReader, int theResponseStatusCode, Map<String, List<String>> theHeaders) throws IOException, BaseServerResponseException {
byte[] contents = IOUtils.toByteArray(theResponseReader);
IBaseBinary resource = (IBaseBinary) getContext().getResourceDefinition("Binary").newInstance();
resource.setContentType(theResponseMimeType);
resource.setContent(contents);
@ -194,7 +199,7 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
@Override
public IBundleProvider invokeServer(RequestDetails theRequest, Object[] theMethodParams) throws InvalidRequestException, InternalErrorException {
theMethodParams[myIdIndex] = theRequest.getId();
theMethodParams[myIdIndex] = MethodUtil.convertIdToType(theRequest.getId(), myIdParameterType);
if (myVersionIdIndex != null) {
theMethodParams[myVersionIdIndex] = new IdDt(theRequest.getId().getVersionIdPart());
}
@ -207,7 +212,7 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
if (retVal.size() == 1 && StringUtils.isNotBlank(ifNoneMatch)) {
List<IBaseResource> responseResources = retVal.getResources(0, 1);
IBaseResource responseResource = responseResources.get(0);
ifNoneMatch = MethodUtil.parseETagValue(ifNoneMatch);
if (responseResource.getIdElement() != null && responseResource.getIdElement().hasVersionIdPart()) {
if (responseResource.getIdElement().getVersionIdPart().equals(ifNoneMatch)) {
@ -230,19 +235,19 @@ public class ReadMethodBinding extends BaseResourceReturningMethodBinding implem
return mySupportsVersion || myVersionIdIndex != null;
}
public static HttpGetClientInvocation createAbsoluteReadInvocation(IdDt theId) {
public static HttpGetClientInvocation createAbsoluteReadInvocation(IIdType theId) {
return new HttpGetClientInvocation(theId.toVersionless().getValue());
}
public static HttpGetClientInvocation createAbsoluteVReadInvocation(IdDt theId) {
public static HttpGetClientInvocation createAbsoluteVReadInvocation(IIdType theId) {
return new HttpGetClientInvocation(theId.getValue());
}
public static HttpGetClientInvocation createReadInvocation(IdDt theId, String theResourceName) {
public static HttpGetClientInvocation createReadInvocation(IIdType theId, String theResourceName) {
return new HttpGetClientInvocation(new IdDt(theResourceName, theId.getIdPart()).getValue());
}
public static HttpGetClientInvocation createVReadInvocation(IdDt theId, String theResourceName) {
public static HttpGetClientInvocation createVReadInvocation(IIdType theId, String theResourceName) {
return new HttpGetClientInvocation(new IdDt(theResourceName, theId.getIdPart(), theId.getVersionIdPart()).getValue());
}

View File

@ -150,7 +150,7 @@ public class SearchMethodBinding extends BaseResourceReturningMethodBinding {
@Override
public boolean incomingServerRequestMatchesMethod(RequestDetails theRequest) {
if (!theRequest.getResourceName().equals(getResourceName())) {
ourLog.trace("Method {} doesn't match because resource name {} != {}", getMethod().getName(), theRequest.getResourceName(), getResourceName());
ourLog.trace("Method {} doesn't match because resource name {} != {}", new Object[] { getMethod().getName(), theRequest.getResourceName(), getResourceName() } );
return false;
}
if (theRequest.getId() != null && myIdParamIndex == null) {

View File

@ -144,7 +144,7 @@ public abstract class BaseQueryParameter implements IParameter {
if (paramList.isEmpty()) {
ourLog.debug("No value for parameter '{}' - Qualified names {} and qualifier whitelist {}", getName(), qualified, getQualifierWhitelist());
ourLog.debug("No value for parameter '{}' - Qualified names {} and qualifier whitelist {}", new Object[] { getName(), qualified, getQualifierWhitelist() } );
if (handlesMissing()) {
return parse(theRequest.getServer().getFhirContext(), paramList);

View File

@ -20,9 +20,10 @@ package ca.uhn.fhir.rest.server;
* #L%
*/
import static org.apache.commons.lang3.StringUtils.isNotBlank;
import static org.apache.commons.lang3.StringUtils.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@ -32,6 +33,7 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
@ -44,7 +46,6 @@ import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
@ -224,7 +225,7 @@ public class Dstu1BundleFactory implements IVersionSpecificBundleFactory {
}
@Override
public void addRootPropertiesToBundle(String theAuthor, String theServerBase, String theCompleteUrl, Integer theTotalResults, BundleTypeEnum theBundleType, InstantDt theLastUpdated) {
public void addRootPropertiesToBundle(String theAuthor, String theServerBase, String theCompleteUrl, Integer theTotalResults, BundleTypeEnum theBundleType, IPrimitiveType<Date> theLastUpdated) {
if (myBundle.getAuthorName().isEmpty()) {
myBundle.getAuthorName().setValue(theAuthor);
}

View File

@ -20,14 +20,15 @@ package ca.uhn.fhir.rest.server;
* #L%
*/
import java.util.Date;
import java.util.List;
import java.util.Set;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
/**
@ -38,7 +39,7 @@ public interface IVersionSpecificBundleFactory {
void addResourcesToBundle(List<IBaseResource> theResult, BundleTypeEnum theBundleType, String theServerBase, BundleInclusionRule theBundleInclusionRule, Set<Include> theIncludes);
void addRootPropertiesToBundle(String theAuthor, String theServerBase, String theCompleteUrl, Integer theTotalResults, BundleTypeEnum theBundleType, InstantDt theLastUpdated);
void addRootPropertiesToBundle(String theAuthor, String theServerBase, String theCompleteUrl, Integer theTotalResults, BundleTypeEnum theBundleType, IPrimitiveType<Date> theLastUpdated);
void initializeBundleFromBundleProvider(RestfulServer theServer, IBundleProvider theResult, EncodingEnum theResponseEncoding, String theServerBase, String theCompleteUrl, boolean thePrettyPrint,
int theOffset, Integer theCount, String theSearchId, BundleTypeEnum theBundleType, Set<Include> theIncludes);

View File

@ -31,10 +31,10 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.rest.method.RequestDetails;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.RestfulServer;
@ -42,28 +42,16 @@ import ca.uhn.fhir.rest.server.RestfulServer.NarrativeModeEnum;
import ca.uhn.fhir.rest.server.RestfulServerUtils;
import ca.uhn.fhir.rest.server.exceptions.BaseServerResponseException;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.util.OperationOutcomeUtil;
public class ExceptionHandlingInterceptor extends InterceptorAdapter {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ExceptionHandlingInterceptor.class);
private Class<?>[] myReturnStackTracesForExceptionTypes;
/**
* If any server methods throw an exception which extends any of the given exception types, the exception
* stack trace will be returned to the user. This can be useful for helping to diagnose issues, but may
* not be desirable for production situations.
*
* @param theExceptionTypes The exception types for which to return the stack trace to the user.
* @return Returns an instance of this interceptor, to allow for easy method chaining.
*/
public ExceptionHandlingInterceptor setReturnStackTracesForExceptionTypes(Class<?>... theExceptionTypes) {
myReturnStackTracesForExceptionTypes = theExceptionTypes;
return this;
}
@Override
public boolean handleException(RequestDetails theRequestDetails, Throwable theException, HttpServletRequest theRequest, HttpServletResponse theResponse) throws ServletException, IOException {
BaseOperationOutcome oo = null;
IBaseOperationOutcome oo = null;
int statusCode = Constants.STATUS_HTTP_500_INTERNAL_ERROR;
FhirContext ctx = theRequestDetails.getServer().getFhirContext();
@ -78,34 +66,31 @@ public class ExceptionHandlingInterceptor extends InterceptorAdapter {
*/
if (oo == null) {
try {
oo = (BaseOperationOutcome) ctx.getResourceDefinition("OperationOutcome").getImplementingClass().newInstance();
RuntimeResourceDefinition ooDef = ctx.getResourceDefinition("OperationOutcome");
oo = (IBaseOperationOutcome) ooDef.getImplementingClass().newInstance();
if (theException instanceof InternalErrorException) {
ourLog.error("Failure during REST processing", theException);
populateDetails(ctx, theException, oo);
} else if (theException instanceof BaseServerResponseException) {
ourLog.warn("Failure during REST processing: {}", theException);
BaseServerResponseException baseServerResponseException = (BaseServerResponseException) theException;
statusCode = baseServerResponseException.getStatusCode();
populateDetails(ctx, theException, oo);
if (baseServerResponseException.getAdditionalMessages() != null) {
for (String next : baseServerResponseException.getAdditionalMessages()) {
OperationOutcomeUtil.addIssue(ctx, oo, "error", next);
}
}
} else {
ourLog.error("Failure during REST processing: " + theException.toString(), theException);
populateDetails(ctx, theException, oo);
statusCode = Constants.STATUS_HTTP_500_INTERNAL_ERROR;
}
} catch (Exception e1) {
ourLog.error("Failed to instantiate OperationOutcome resource instance", e1);
throw new ServletException("Failed to instantiate OperationOutcome resource instance", e1);
}
BaseIssue issue = oo.addIssue();
issue.getSeverityElement().setValue("error");
if (theException instanceof InternalErrorException) {
ourLog.error("Failure during REST processing", theException);
populateDetails(theException, issue);
} else if (theException instanceof BaseServerResponseException) {
ourLog.warn("Failure during REST processing: {}", theException);
BaseServerResponseException baseServerResponseException = (BaseServerResponseException) theException;
statusCode = baseServerResponseException.getStatusCode();
populateDetails(theException, issue);
if (baseServerResponseException.getAdditionalMessages() != null) {
for (String next : baseServerResponseException.getAdditionalMessages()) {
BaseIssue issue2 = oo.addIssue();
issue2.getSeverityElement().setValue("error");
issue2.setDetails(next);
}
}
} else {
ourLog.error("Failure during REST processing: " + theException.toString(), theException);
populateDetails(theException, issue);
statusCode = Constants.STATUS_HTTP_500_INTERNAL_ERROR;
}
} else {
ourLog.error("Unknown error during processing", theException);
}
@ -127,30 +112,44 @@ public class ExceptionHandlingInterceptor extends InterceptorAdapter {
boolean requestIsBrowser = RestfulServer.requestIsBrowser(theRequest);
String fhirServerBase = theRequestDetails.getFhirServerBase();
RestfulServerUtils.streamResponseAsResource(theRequestDetails.getServer(), theResponse, oo, RestfulServerUtils.determineResponseEncodingNoDefault(theRequest), true, requestIsBrowser,
NarrativeModeEnum.NORMAL, statusCode, false, fhirServerBase, false);
RestfulServerUtils.streamResponseAsResource(theRequestDetails.getServer(), theResponse, oo, RestfulServerUtils.determineResponseEncodingNoDefault(theRequest), true, requestIsBrowser, NarrativeModeEnum.NORMAL, statusCode, false, fhirServerBase, false);
// theResponse.setStatus(statusCode);
// theRequestDetails.getServer().addHeadersToResponse(theResponse);
// theResponse.setContentType("text/plain");
// theResponse.setCharacterEncoding("UTF-8");
// theResponse.getWriter().append(theException.getMessage());
// theResponse.getWriter().close();
// theResponse.setStatus(statusCode);
// theRequestDetails.getServer().addHeadersToResponse(theResponse);
// theResponse.setContentType("text/plain");
// theResponse.setCharacterEncoding("UTF-8");
// theResponse.getWriter().append(theException.getMessage());
// theResponse.getWriter().close();
return false;
}
private void populateDetails(Throwable theException, BaseIssue issue) {
private void populateDetails(FhirContext theCtx, Throwable theException, IBaseOperationOutcome theOo) {
if (myReturnStackTracesForExceptionTypes != null) {
for (Class<?> next : myReturnStackTracesForExceptionTypes) {
if (next.isAssignableFrom(theException.getClass())) {
issue.getDetailsElement().setValue(theException.getMessage() + "\n\n" + ExceptionUtils.getStackTrace(theException));
String detailsValue = theException.getMessage() + "\n\n" + ExceptionUtils.getStackTrace(theException);
OperationOutcomeUtil.addIssue(theCtx, theOo, "error", detailsValue);
return;
}
}
}
issue.getDetailsElement().setValue(theException.getMessage());
OperationOutcomeUtil.addIssue(theCtx, theOo, "error", theException.getMessage());
}
/**
* If any server methods throw an exception which extends any of the given exception types, the exception stack trace
* will be returned to the user. This can be useful for helping to diagnose issues, but may not be desirable for
* production situations.
*
* @param theExceptionTypes
* The exception types for which to return the stack trace to the user.
* @return Returns an instance of this interceptor, to allow for easy method chaining.
*/
public ExceptionHandlingInterceptor setReturnStackTracesForExceptionTypes(Class<?>... theExceptionTypes) {
myReturnStackTracesForExceptionTypes = theExceptionTypes;
return this;
}
}

View File

@ -0,0 +1,124 @@
package ca.uhn.fhir.util;
import static org.apache.commons.lang3.StringUtils.*;
import java.util.List;
import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementCompositeDefinition;
import ca.uhn.fhir.context.BaseRuntimeElementDefinition;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
/**
* Utilities for dealing with OperationOutcome resources across various model versions
*/
public class OperationOutcomeUtil {
/**
* Add an issue to an OperationOutcome
*
* @param theCtx The fhir context
* @param theOperationOutcome The OO resource to add to
* @param theSeverity The severity (e.g. "error")
* @param theDetails The details string
*/
public static void addIssue(FhirContext theCtx, IBaseOperationOutcome theOperationOutcome, String theSeverity, String theDetails) {
IBase issue = createIssue(theCtx, theOperationOutcome);
populateDetails(theCtx, issue, theSeverity, theDetails, null);
}
/**
* Add an issue to an OperationOutcome
*
* @param theCtx The fhir context
* @param theOperationOutcome The OO resource to add to
* @param theSeverity The severity (e.g. "error")
* @param theDetails The details string
*/
public static void addIssue(FhirContext theCtx, IBaseOperationOutcome theOperationOutcome, String theSeverity, String theDetails, String theLocation) {
IBase issue = createIssue(theCtx, theOperationOutcome);
populateDetails(theCtx, issue, theSeverity, theDetails, theLocation);
}
private static IBase createIssue(FhirContext theCtx, IBaseResource theOutcome) {
RuntimeResourceDefinition ooDef = theCtx.getResourceDefinition(theOutcome);
BaseRuntimeChildDefinition issueChild = ooDef.getChildByName("issue");
BaseRuntimeElementCompositeDefinition<?> issueElement = (BaseRuntimeElementCompositeDefinition<?>) issueChild.getChildByName("issue");
IBase issue = issueElement.newInstance();
issueChild.getMutator().addValue(theOutcome, issue);
return issue;
}
private static void populateDetails(FhirContext theCtx, IBase theIssue, String theSeverity, String theDetails, String theLocation) {
BaseRuntimeElementCompositeDefinition<?> issueElement = (BaseRuntimeElementCompositeDefinition<?>) theCtx.getElementDefinition(theIssue.getClass());
BaseRuntimeChildDefinition detailsChild = issueElement.getChildByName("details");
BaseRuntimeElementDefinition<?> stringDef = theCtx.getElementDefinition("string");
BaseRuntimeChildDefinition severityChild = issueElement.getChildByName("severity");
BaseRuntimeChildDefinition locationChild = issueElement.getChildByName("location");
IPrimitiveType<?> severityElem = (IPrimitiveType<?>) severityChild.getChildByName("severity").newInstance(severityChild.getInstanceConstructorArguments());
severityElem.setValueAsString(theSeverity);
severityChild.getMutator().addValue(theIssue, severityElem);
IPrimitiveType<?> string = (IPrimitiveType<?>) stringDef.newInstance();
string.setValueAsString(theDetails);
detailsChild.getMutator().setValue(theIssue, string);
if (isNotBlank(theLocation)) {
IPrimitiveType<?> locationElem = (IPrimitiveType<?>) locationChild.getChildByName("location").newInstance(locationChild.getInstanceConstructorArguments());
locationElem.setValueAsString(theLocation);
locationChild.getMutator().addValue(theIssue, locationElem);
}
}
/**
* Returns true if the given OperationOutcome has 1 or more Operation.issue repetitions
*/
public static boolean hasIssues(FhirContext theCtx, IBaseOperationOutcome theOutcome) {
if (theOutcome == null) {
return false;
}
RuntimeResourceDefinition ooDef = theCtx.getResourceDefinition(theOutcome);
BaseRuntimeChildDefinition issueChild = ooDef.getChildByName("issue");
return issueChild.getAccessor().getValues(theOutcome).size() > 0;
}
public static String getFirstIssueDetails(FhirContext theCtx, IBaseOperationOutcome theOutcome) {
return getFirstIssueStringPart(theCtx, theOutcome, "details");
}
public static String getFirstIssueLocation(FhirContext theCtx, IBaseOperationOutcome theOutcome) {
return getFirstIssueStringPart(theCtx, theOutcome, "location");
}
private static String getFirstIssueStringPart(FhirContext theCtx, IBaseOperationOutcome theOutcome, String name) {
if (theOutcome == null) {
return null;
}
RuntimeResourceDefinition ooDef = theCtx.getResourceDefinition(theOutcome);
BaseRuntimeChildDefinition issueChild = ooDef.getChildByName("issue");
List<IBase> issues = issueChild.getAccessor().getValues(theOutcome);
if (issues.isEmpty()) {
return null;
}
IBase issue = issues.get(0);
BaseRuntimeElementCompositeDefinition<?> issueElement = (BaseRuntimeElementCompositeDefinition<?>) theCtx.getElementDefinition(issue.getClass());
BaseRuntimeChildDefinition detailsChild = issueElement.getChildByName(name);
List<IBase> details = detailsChild.getAccessor().getValues(issue);
if (details.isEmpty()) {
return null;
}
return ((IPrimitiveType<?>)details.get(0)).getValueAsString();
}
}

View File

@ -1656,7 +1656,7 @@ public class XmlUtil {
version = attrs.getValue(BUNDLE_VERSION);
}
if (ourLog.isDebugEnabled()) {
ourLog.debug("FHIR XML procesing will use StAX implementation at {}\n Title: {}\n Symbolic name: {}\n Vendor: {}\n Version: {}", rootUrl, title, symbolicName, vendor, version);
ourLog.debug("FHIR XML procesing will use StAX implementation at {}\n Title: {}\n Symbolic name: {}\n Vendor: {}\n Version: {}", new Object[] { rootUrl, title, symbolicName, vendor, version } );
} else {
ourLog.info("FHIR XML procesing will use StAX implementation '{}' version '{}'", title, version);
}

View File

@ -25,12 +25,13 @@ import java.util.Iterator;
import java.util.List;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
import ca.uhn.fhir.util.OperationOutcomeUtil;
/**
* Resource validator, which checks resources for compliance against various validation schemes (schemas, schematrons, etc.)
@ -148,9 +149,9 @@ public class FhirValidator {
next.validateBundle(ctx);
}
BaseOperationOutcome oo = ctx.getOperationOutcome();
if (oo != null && oo.getIssue().size() > 0) {
throw new ValidationFailureException(oo);
IBaseOperationOutcome oo = ctx.getOperationOutcome();
if (oo != null && OperationOutcomeUtil.hasIssues(myContext, oo)) {
throw new ValidationFailureException(myContext, oo);
}
}
@ -168,7 +169,7 @@ public class FhirValidator {
public void validate(IResource theResource) throws ValidationFailureException {
ValidationResult validationResult = validateWithResult(theResource);
if (!validationResult.isSuccessful()) {
throw new ValidationFailureException(validationResult.getOperationOutcome());
throw new ValidationFailureException(myContext, validationResult.getOperationOutcome());
}
}
@ -189,8 +190,8 @@ public class FhirValidator {
next.validateBundle(ctx);
}
BaseOperationOutcome oo = ctx.getOperationOutcome();
return ValidationResult.valueOf(oo);
IBaseOperationOutcome oo = ctx.getOperationOutcome();
return ValidationResult.valueOf(myContext, oo);
}
/**
@ -209,7 +210,7 @@ public class FhirValidator {
next.validateResource(ctx);
}
BaseOperationOutcome oo = ctx.getOperationOutcome();
return ValidationResult.valueOf(oo);
IBaseOperationOutcome oo = ctx.getOperationOutcome();
return ValidationResult.valueOf(myContext, oo);
}
}

View File

@ -51,6 +51,7 @@ import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.util.OperationOutcomeUtil;
class SchemaBaseValidator implements IValidator {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(SchemaBaseValidator.class);
@ -85,7 +86,8 @@ class SchemaBaseValidator implements IValidator {
validator.setErrorHandler(handler);
String encodedResource = theContext.getXmlEncodedResource();
// ourLog.info(new FhirContext().newXmlParser().setPrettyPrint(true).encodeBundleToString((Bundle) theContext.getResource()));
// ourLog.info(new FhirContext().newXmlParser().setPrettyPrint(true).encodeBundleToString((Bundle)
// theContext.getResource()));
validator.validate(new StreamSource(new StringReader(encodedResource)));
} catch (SAXException e) {
@ -123,25 +125,25 @@ class SchemaBaseValidator implements IValidator {
private Source loadXml(String theVersion, String theSystemId, String theSchemaName) {
String pathToBase = myCtx.getVersion().getPathToSchemaDefinitions() + '/' + theSchemaName;
ourLog.debug("Going to load resource: {}", pathToBase);
InputStream baseIs = FhirValidator.class.getClassLoader().getResourceAsStream(pathToBase);
InputStream baseIs = FhirValidator.class.getResourceAsStream(pathToBase);
if (baseIs == null) {
throw new InternalErrorException("No FHIR-BASE schema found");
}
baseIs = new BOMInputStream(baseIs, false);
InputStreamReader baseReader = new InputStreamReader(baseIs, Charset.forName("UTF-8"));
Source baseSource = new StreamSource(baseReader, theSystemId);
baseIs = new BOMInputStream(baseIs, false);
InputStreamReader baseReader = new InputStreamReader(baseIs, Charset.forName("UTF-8"));
Source baseSource = new StreamSource(baseReader, theSystemId);
// String schema;
// try {
// schema = IOUtils.toString(baseIs, Charset.forName("UTF-8"));
// } catch (IOException e) {
// throw new InternalErrorException(e);
// }
//
// ourLog.info("Schema is:\n{}", schema);
//
// Source baseSource = new StreamSource(new StringReader(schema), theSystemId);
// Source baseSource = new StreamSource(baseIs, theSystemId);
// String schema;
// try {
// schema = IOUtils.toString(baseIs, Charset.forName("UTF-8"));
// } catch (IOException e) {
// throw new InternalErrorException(e);
// }
//
// ourLog.info("Schema is:\n{}", schema);
//
// Source baseSource = new StreamSource(new StringReader(schema), theSystemId);
// Source baseSource = new StreamSource(baseIs, theSystemId);
return baseSource;
}
@ -167,11 +169,10 @@ class SchemaBaseValidator implements IValidator {
myContext = theContext;
}
private void addIssue(SAXParseException theException, String severity) {
BaseIssue issue = myContext.getOperationOutcome().addIssue();
issue.getSeverityElement().setValue(severity);
issue.getDetailsElement().setValue(theException.getLocalizedMessage());
issue.addLocation("Line[" + theException.getLineNumber() + "] Col[" + theException.getColumnNumber() + "]");
private void addIssue(SAXParseException theException, String theSeverity) {
String details = theException.getLocalizedMessage();
String location = "Line[" + theException.getLineNumber() + "] Col[" + theException.getColumnNumber() + "]";
OperationOutcomeUtil.addIssue(myContext.getFhirContext(), myContext.getOperationOutcome(), theSeverity, details, location);
}
@Override
@ -205,12 +206,12 @@ class SchemaBaseValidator implements IValidator {
input.setPublicId(thePublicId);
input.setSystemId(theSystemId);
input.setBaseURI(theBaseURI);
// String pathToBase = "ca/uhn/fhir/model/" + myVersion + "/schema/" + theSystemId;
// String pathToBase = "ca/uhn/fhir/model/" + myVersion + "/schema/" + theSystemId;
String pathToBase = myCtx.getVersion().getPathToSchemaDefinitions() + '/' + theSystemId;
ourLog.debug("Loading referenced schema file: " + pathToBase);
InputStream baseIs = FhirValidator.class.getClassLoader().getResourceAsStream(pathToBase);
InputStream baseIs = FhirValidator.class.getResourceAsStream(pathToBase);
if (baseIs == null) {
throw new InternalErrorException("Schema file not found: " + pathToBase);
}

View File

@ -34,8 +34,8 @@ import org.oclc.purl.dsdl.svrl.SchematronOutputType;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.api.BundleEntry;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.util.OperationOutcomeUtil;
import com.phloc.commons.error.IResourceError;
import com.phloc.commons.error.IResourceErrorGroup;
@ -70,23 +70,25 @@ public class SchematronBaseValidator implements IValidator {
}
for (IResourceError next : errors.getAllErrors().getAllResourceErrors()) {
BaseIssue issue = theCtx.getOperationOutcome().addIssue();
String severity;
switch (next.getErrorLevel()) {
case ERROR:
issue.getSeverityElement().setValue("error");
severity = ("error");
break;
case FATAL_ERROR:
issue.getSeverityElement().setValue("fatal");
severity = ("fatal");
break;
case WARN:
issue.getSeverityElement().setValue("warning");
severity = ("warning");
break;
case INFO:
case SUCCESS:
default:
continue;
}
issue.getDetailsElement().setValue(next.getAsString(Locale.getDefault()));
String details = next.getAsString(Locale.getDefault());
OperationOutcomeUtil.addIssue(myCtx, theCtx.getOperationOutcome(), severity, details);
}
}
@ -107,7 +109,7 @@ public class SchematronBaseValidator implements IValidator {
String pathToBase = myCtx.getVersion().getPathToSchemaDefinitions() + '/' + theCtx.getFhirContext().getResourceDefinition(theCtx.getResource()).getBaseDefinition().getName().toLowerCase()
+ ".sch";
InputStream baseIs = FhirValidator.class.getClassLoader().getResourceAsStream(pathToBase);
InputStream baseIs = FhirValidator.class.getResourceAsStream(pathToBase);
if (baseIs == null) {
throw new InternalErrorException("No schematron found for resource type: "
+ theCtx.getFhirContext().getResourceDefinition(theCtx.getResource()).getBaseDefinition().getImplementingClass().getCanonicalName());

View File

@ -20,18 +20,18 @@ package ca.uhn.fhir.validation;
* #L%
*/
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
class ValidationContext<T> {
private final IEncoder myEncoder;
private final FhirContext myFhirContext;
private BaseOperationOutcome myOperationOutcome;
private IBaseOperationOutcome myOperationOutcome;
private final T myResource;
private String myXmlEncodedResource;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(ValidationContext.class);
@ -45,10 +45,10 @@ private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger
return myFhirContext;
}
public BaseOperationOutcome getOperationOutcome() {
public IBaseOperationOutcome getOperationOutcome() {
if (myOperationOutcome == null) {
try {
myOperationOutcome = (BaseOperationOutcome) myFhirContext.getResourceDefinition("OperationOutcome").getImplementingClass().newInstance();
myOperationOutcome = (IBaseOperationOutcome) myFhirContext.getResourceDefinition("OperationOutcome").getImplementingClass().newInstance();
} catch (Exception e1) {
ourLog.error("Failed to instantiate OperationOutcome resource instance", e1);
throw new InternalErrorException("Failed to instantiate OperationOutcome resource instance", e1);

View File

@ -20,20 +20,23 @@ package ca.uhn.fhir.validation;
* #L%
*/
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.util.OperationOutcomeUtil;
public class ValidationFailureException extends RuntimeException {
private static final long serialVersionUID = 1L;
private BaseOperationOutcome myOperationOutcome;
private IBaseOperationOutcome myOperationOutcome;
// public ValidationFailureException(String theProblem) {
// this(theProblem, IssueSeverityEnum.FATAL, null);
// }
private static String toDescription(BaseOperationOutcome theOo) {
private static String toDescription(FhirContext theCtx, IBaseOperationOutcome theOo) {
StringBuilder b = new StringBuilder();
b.append(theOo.getIssueFirstRep().getDetailsElement().getValue());
b.append(OperationOutcomeUtil.getFirstIssueDetails(theCtx, theOo));
// b.append(" - ");
// b.append(theOo.getIssueFirstRep().getLocationFirstRep().getValue());
return b.toString();
@ -49,12 +52,12 @@ public class ValidationFailureException extends RuntimeException {
// myOperationOutcome.addIssue().setSeverity(theSeverity).setDetails(theProblem);
// }
public ValidationFailureException(BaseOperationOutcome theOperationOutcome) {
super(toDescription(theOperationOutcome));
public ValidationFailureException(FhirContext theCtx, IBaseOperationOutcome theOperationOutcome) {
super(toDescription(theCtx, theOperationOutcome));
myOperationOutcome = theOperationOutcome;
}
public BaseOperationOutcome getOperationOutcome() {
public IBaseOperationOutcome getOperationOutcome() {
return myOperationOutcome;
}

View File

@ -20,7 +20,10 @@ package ca.uhn.fhir.validation;
* #L%
*/
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.util.OperationOutcomeUtil;
/**
* Encapsulates the results of validation
@ -29,50 +32,48 @@ import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
* @since 0.7
*/
public class ValidationResult {
private BaseOperationOutcome myOperationOutcome;
private boolean isSuccessful;
private IBaseOperationOutcome myOperationOutcome;
private boolean myIsSuccessful;
private FhirContext myCtx;
private ValidationResult(BaseOperationOutcome myOperationOutcome, boolean isSuccessful) {
this.myOperationOutcome = myOperationOutcome;
this.isSuccessful = isSuccessful;
}
private ValidationResult(FhirContext theCtx, IBaseOperationOutcome theOperationOutcome, boolean isSuccessful) {
this.myCtx = theCtx;
this.myOperationOutcome = theOperationOutcome;
this.myIsSuccessful = isSuccessful;
}
public static ValidationResult valueOf(BaseOperationOutcome myOperationOutcome) {
boolean noIssues = myOperationOutcome == null || myOperationOutcome.getIssue().isEmpty();
return new ValidationResult(myOperationOutcome, noIssues);
}
public static ValidationResult valueOf(FhirContext theCtx, IBaseOperationOutcome myOperationOutcome) {
boolean noIssues = !OperationOutcomeUtil.hasIssues(theCtx, myOperationOutcome);
return new ValidationResult(theCtx, myOperationOutcome, noIssues);
}
public BaseOperationOutcome getOperationOutcome() {
return myOperationOutcome;
}
public IBaseOperationOutcome getOperationOutcome() {
return myOperationOutcome;
}
@Override
public String toString() {
return "ValidationResult{" +
"myOperationOutcome=" + myOperationOutcome +
", isSuccessful=" + isSuccessful +
", description='" + toDescription() + '\'' +
'}';
}
@Override
public String toString() {
return "ValidationResult{" + "myOperationOutcome=" + myOperationOutcome + ", isSuccessful=" + myIsSuccessful + ", description='" + toDescription() + '\'' + '}';
}
private String toDescription() {
StringBuilder b = new StringBuilder(100);
if (myOperationOutcome != null && myOperationOutcome.getIssue().size() > 0) {
BaseOperationOutcome.BaseIssue issueFirstRep = myOperationOutcome.getIssueFirstRep();
b.append(issueFirstRep.getDetailsElement().getValue());
b.append(" - ");
b.append(issueFirstRep.getLocationFirstRep().getValue());
}else {
b.append("No issues");
}
return b.toString();
}
private String toDescription() {
StringBuilder b = new StringBuilder(100);
if (myOperationOutcome != null && OperationOutcomeUtil.hasIssues(myCtx, myOperationOutcome)) {
b.append(OperationOutcomeUtil.getFirstIssueDetails(myCtx, myOperationOutcome));
b.append(" - ");
b.append(OperationOutcomeUtil.getFirstIssueLocation(myCtx, myOperationOutcome));
} else {
b.append("No issues");
}
return b.toString();
}
/**
* Was the validation successful
* @return true if the validation was successful
*/
public boolean isSuccessful() {
return isSuccessful;
}
/**
* Was the validation successful
*
* @return true if the validation was successful
*/
public boolean isSuccessful() {
return myIsSuccessful;
}
}

View File

@ -0,0 +1,6 @@
package org.hl7.fhir.instance.model.api;
public interface IBaseOperationOutcome extends IBaseResource {
}

View File

@ -1,6 +1,7 @@
package org.hl7.fhir.instance.model.api;
/*
* #%L
* HAPI FHIR - Core Library
@ -21,11 +22,23 @@ package org.hl7.fhir.instance.model.api;
* #L%
*/
/**
* Base interface for ID datatype.
*
* <p>
* <b>Concrete Implementations:</b> This interface is often returned and/or accepted by methods in HAPI's API
* where either {@link ca.uhn.fhir.model.primitive.IdDt} (the HAPI structure ID type) or
* <code>org.hl7.fhir.instance.model.IdType</code> (the RI structure ID type) will be used, depending on
* which version of the strctures your application is using.
* </p>
*/
public interface IIdType {
boolean isEmpty();
/**
* Returns <code>true</code> if the ID is a local reference (in other words, it begins with the '#' character)
*/
boolean isLocal();
/**
@ -42,8 +55,16 @@ public interface IIdType {
*/
String getIdPart();
/**
* Returns <code>true</code> if this ID contains an actual ID part. For example, the ID part is
* the '123' in the following ID: <code>http://example.com/fhir/Patient/123/_history/55</code>
*/
boolean hasIdPart();
/**
* Returns the server base URL if this ID contains one. For example, the base URL is
* the 'http://example.com/fhir' in the following ID: <code>http://example.com/fhir/Patient/123/_history/55</code>
*/
String getBaseUrl();
IIdType toUnqualifiedVersionless();
@ -72,4 +93,10 @@ public interface IIdType {
Long getIdPartAsLong();
boolean hasBaseUrl();
IIdType withVersion(String theVersion);
void applyTo(IBaseResource theResource);
}

View File

@ -62,18 +62,17 @@
<version>${thymeleaf-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j_version}</version>
</dependency>
<!-- <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-nop</artifactId>
<version>${slf4j_version}</version> </dependency> -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback_version}</version>
</dependency>
<!-- Use an older version of SLF4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.0</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.6.0</version>
</dependency>
<!-- Test Database -->
<dependency>

View File

@ -20,6 +20,7 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="var" path="M2_REPO/org/slf4j/slf4j-api/1.6.0/slf4j-api-1.6.0.jar"/>
<classpathentry combineaccessrules="false" exported="true" kind="src" path="/hapi-fhir-base"/>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>

View File

@ -140,7 +140,7 @@ public abstract class BaseFhirDao implements IDao {
private ISearchParamExtractor mySearchParamExtractor;
protected void createForcedIdIfNeeded(ResourceTable entity, IdDt id) {
protected void createForcedIdIfNeeded(ResourceTable entity, IIdType id) {
if (id.isEmpty() == false && id.hasIdPart()) {
if (isValidPid(id)) {
return;
@ -276,13 +276,13 @@ public abstract class BaseFhirDao implements IDao {
values.addAll(t.getValues(theResource, nextPathTrimmed));
} catch (Exception e) {
RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource);
ourLog.warn("Failed to index values from path[{}] in resource type[{}]: ", nextPathTrimmed, def.getName(), e.toString());
ourLog.warn("Failed to index values from path[{}] in resource type[{}]: ", new Object[] { nextPathTrimmed, def.getName(), e.toString() } );
}
}
return values;
}
private void findMatchingTagIds(String theResourceName, IdDt theResourceId, Set<Long> tagIds, Class<? extends BaseTag> entityClass) {
private void findMatchingTagIds(String theResourceName, IIdType theResourceId, Set<Long> tagIds, Class<? extends BaseTag> entityClass) {
{
CriteriaBuilder builder = myEntityManager.getCriteriaBuilder();
CriteriaQuery<Tuple> cq = builder.createTupleQuery();
@ -375,7 +375,7 @@ public abstract class BaseFhirDao implements IDao {
}
}
protected TagList getTags(Class<? extends IResource> theResourceType, IdDt theResourceId) {
protected TagList getTags(Class<? extends IResource> theResourceType, IIdType theResourceId) {
String resourceName = null;
if (theResourceType != null) {
resourceName = toResourceName(theResourceType);
@ -610,7 +610,7 @@ public abstract class BaseFhirDao implements IDao {
List<IdDt> profiles = ResourceMetadataKeyEnum.PROFILES.get(theResource);
if (profiles != null) {
for (IdDt next : profiles) {
for (IIdType next : profiles) {
TagDefinition tag = getTag(TagTypeEnum.PROFILE, NS_JPA_PROFILE, next.getValue(), null);
theEntity.addTag(tag);
theEntity.setHasTags(true);

View File

@ -577,7 +577,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
if (isBlank(ref.getChain())) {
if (resourceId.contains("/")) {
IdDt dt = new IdDt(resourceId);
IIdType dt = new IdDt(resourceId);
resourceId = dt.getIdPart();
}
Long targetPid = translateForcedIdToPid(new IdDt(resourceId));
@ -780,7 +780,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
}
@Override
public void addTag(IdDt theId, TagTypeEnum theTagType, String theScheme, String theTerm, String theLabel) {
public void addTag(IIdType theId, TagTypeEnum theTagType, String theScheme, String theTerm, String theLabel) {
StopWatch w = new StopWatch();
BaseHasResource entity = readEntity(theId);
if (entity == null) {
@ -1062,10 +1062,10 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
}
@Override
public DaoMethodOutcome delete(IdDt theId) {
public DaoMethodOutcome delete(IIdType theId) {
StopWatch w = new StopWatch();
final ResourceTable entity = readEntityLatestVersion(theId);
if (theId.hasVersionIdPart() && theId.getVersionIdPartAsLong().longValue() != entity.getVersion()) {
if (theId.hasVersionIdPart() && Long.parseLong(theId.getVersionIdPart()) != entity.getVersion()) {
throw new InvalidRequestException("Trying to update " + theId + " but this is not the current version");
}
@ -1169,7 +1169,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
}
@Override
public TagList getTags(IdDt theResourceId) {
public TagList getTags(IIdType theResourceId) {
StopWatch w = new StopWatch();
TagList retVal = super.getTags(myResourceType, theResourceId);
ourLog.info("Processed getTags on {} in {}ms", theResourceId, w.getMillisAndRestart());
@ -1185,7 +1185,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
}
@Override
public IBundleProvider history(final IdDt theId, final Date theSince) {
public IBundleProvider history(final IIdType theId, final Date theSince) {
final InstantDt end = createHistoryToTimestamp();
final String resourceType = getContext().getResourceDefinition(myResourceType).getName();
@ -1375,7 +1375,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
}
@Override
public MetaDt metaAddOperation(IdDt theResourceId, MetaDt theMetaAdd) {
public MetaDt metaAddOperation(IIdType theResourceId, MetaDt theMetaAdd) {
StopWatch w = new StopWatch();
BaseHasResource entity = readEntity(theResourceId);
if (entity == null) {
@ -1415,7 +1415,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
}
@Override
public MetaDt metaDeleteOperation(IdDt theResourceId, MetaDt theMetaDel) {
public MetaDt metaDeleteOperation(IIdType theResourceId, MetaDt theMetaDel) {
StopWatch w = new StopWatch();
BaseHasResource entity = readEntity(theResourceId);
if (entity == null) {
@ -1461,7 +1461,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
}
@Override
public MetaDt metaGetOperation(IdDt theId) {
public MetaDt metaGetOperation(IIdType theId) {
Long pid = super.translateForcedIdToPid(theId);
String sql = "SELECT d FROM TagDefinition d WHERE d.myId IN (SELECT DISTINCT t.myTagId FROM ResourceTag t WHERE t.myResourceType = :res_type AND t.myResourceId = :res_id)";
@ -1494,7 +1494,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
}
@Override
public T read(IdDt theId) {
public T read(IIdType theId) {
validateResourceTypeAndThrowIllegalArgumentException(theId);
StopWatch w = new StopWatch();
@ -1513,7 +1513,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
}
@Override
public BaseHasResource readEntity(IdDt theId) {
public BaseHasResource readEntity(IIdType theId) {
boolean checkForForcedId = true;
BaseHasResource entity = readEntity(theId, checkForForcedId);
@ -1522,13 +1522,13 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
}
@Override
public BaseHasResource readEntity(IdDt theId, boolean theCheckForForcedId) {
public BaseHasResource readEntity(IIdType theId, boolean theCheckForForcedId) {
validateResourceTypeAndThrowIllegalArgumentException(theId);
Long pid = translateForcedIdToPid(theId);
BaseHasResource entity = myEntityManager.find(ResourceTable.class, pid);
if (theId.hasVersionIdPart()) {
if (entity.getVersion() != theId.getVersionIdPartAsLong()) {
if (entity.getVersion() != Long.parseLong(theId.getVersionIdPart())) {
entity = null;
}
}
@ -1539,7 +1539,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
"SELECT t from ResourceHistoryTable t WHERE t.myResourceId = :RID AND t.myResourceType = :RTYP AND t.myResourceVersion = :RVER", ResourceHistoryTable.class);
q.setParameter("RID", pid);
q.setParameter("RTYP", myResourceName);
q.setParameter("RVER", theId.getVersionIdPartAsLong());
q.setParameter("RVER", Long.parseLong(theId.getVersionIdPart()));
entity = q.getSingleResult();
}
if (entity == null) {
@ -1555,7 +1555,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
return entity;
}
private ResourceTable readEntityLatestVersion(IdDt theId) {
private ResourceTable readEntityLatestVersion(IIdType theId) {
ResourceTable entity = myEntityManager.find(ResourceTable.class, translateForcedIdToPid(theId));
if (entity == null) {
throw new ResourceNotFoundException(theId);
@ -1565,7 +1565,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
}
@Override
public void removeTag(IdDt theId, TagTypeEnum theTagType, String theScheme, String theTerm) {
public void removeTag(IIdType theId, TagTypeEnum theTagType, String theScheme, String theTerm) {
StopWatch w = new StopWatch();
BaseHasResource entity = readEntity(theId);
if (entity == null) {
@ -1728,7 +1728,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
previouslyLoadedPids.add(next.getIdElement().toUnqualifiedVersionless());
}
Set<IdDt> includePids = new HashSet<IdDt>();
Set<IIdType> includePids = new HashSet<IIdType>();
List<IBaseResource> resources = retVal;
do {
includePids.clear();
@ -1754,7 +1754,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
continue;
}
IdDt nextId = rr.getReference().toUnqualified();
IIdType nextId = rr.getReference().toUnqualified();
if (!previouslyLoadedPids.contains(nextId)) {
includePids.add(nextId);
previouslyLoadedPids.add(nextId);
@ -1842,7 +1842,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
} else {
for (IQueryParameterType next : nextValue) {
String value = next.getValueAsQueryToken();
IdDt valueId = new IdDt(value);
IIdType valueId = new IdDt(value);
try {
long valueLong = translateForcedIdToPid(valueId);
joinPids.add(valueLong);
@ -2039,7 +2039,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
final ResourceTable entity;
IdDt resourceId;
IIdType resourceId;
if (isNotBlank(theMatchUrl)) {
Set<Long> match = processMatchUrl(theMatchUrl, myResourceType);
if (match.size() > 1) {
@ -2067,7 +2067,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
}
}
if (resourceId.hasVersionIdPart() && resourceId.getVersionIdPartAsLong().longValue() != entity.getVersion()) {
if (resourceId.hasVersionIdPart() && Long.parseLong(resourceId.getVersionIdPart()) != entity.getVersion()) {
throw new InvalidRequestException("Trying to update " + resourceId + " but this is not the current version");
}
@ -2078,7 +2078,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
return toMethodOutcome(savedEntity, theResource).setCreated(false);
}
private void validateGivenIdIsAppropriateToRetrieveResource(IdDt theId, BaseHasResource entity) {
private void validateGivenIdIsAppropriateToRetrieveResource(IIdType theId, BaseHasResource entity) {
if (entity.getForcedId() != null) {
if (theId.isIdPartValidLong()) {
// This means that the resource with the given numeric ID exists, but it has a "forced ID", meaning that
@ -2097,7 +2097,7 @@ public abstract class BaseFhirResourceDao<T extends IResource> extends BaseFhirD
}
}
private void validateResourceTypeAndThrowIllegalArgumentException(IdDt theId) {
private void validateResourceTypeAndThrowIllegalArgumentException(IIdType theId) {
if (theId.hasResourceType() && !theId.getResourceType().equals(myResourceName)) {
throw new IllegalArgumentException("Incorrect resource type (" + theId.getResourceType() + ") for this DAO, wanted: " + myResourceName);
}

View File

@ -50,7 +50,7 @@ public class BaseSearchParamExtractor {
values.addAll(t.getValues(theResource, nextPathTrimmed));
} catch (Exception e) {
RuntimeResourceDefinition def = myContext.getResourceDefinition(theResource);
ourLog.warn("Failed to index values from path[{}] in resource type[{}]: ", nextPathTrimmed, def.getName(), e.toString());
ourLog.warn("Failed to index values from path[{}] in resource type[{}]: ", new Object[] { nextPathTrimmed, def.getName(), e.toString() } );
}
}
return values;

View File

@ -32,6 +32,7 @@ import java.util.Set;
import javax.persistence.TypedQuery;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.springframework.jmx.access.InvalidInvocationException;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@ -363,7 +364,7 @@ public class FhirSystemDaoDstu2 extends BaseFhirSystemDao<Bundle> {
private static void handleTransactionCreateOrUpdateOutcome(Map<IdDt, IdDt> idSubstitutions, Map<IdDt, DaoMethodOutcome> idToPersistedOutcome, IdDt nextResourceId, DaoMethodOutcome outcome,
Entry newEntry, String theResourceType) {
IdDt newId = outcome.getId().toUnqualifiedVersionless();
IdDt newId = (IdDt) outcome.getId().toUnqualifiedVersionless();
IdDt resourceId = isPlaceholder(nextResourceId) ? nextResourceId : nextResourceId.toUnqualifiedVersionless();
if (newId.equals(resourceId) == false) {
idSubstitutions.put(resourceId, newId);

View File

@ -24,19 +24,20 @@ import java.util.Date;
import java.util.Map;
import java.util.Set;
import org.hl7.fhir.instance.model.api.IIdType;
import ca.uhn.fhir.jpa.entity.BaseHasResource;
import ca.uhn.fhir.jpa.entity.TagTypeEnum;
import ca.uhn.fhir.model.api.IQueryParameterType;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.dstu2.composite.MetaDt;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.server.IBundleProvider;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
public interface IFhirResourceDao<T extends IResource> extends IDao {
void addTag(IdDt theId, TagTypeEnum theTagType, String theScheme, String theTerm, String theLabel);
void addTag(IIdType theId, TagTypeEnum theTagType, String theScheme, String theTerm, String theLabel);
DaoMethodOutcome create(T theResource);
@ -48,7 +49,7 @@ public interface IFhirResourceDao<T extends IResource> extends IDao {
*/
DaoMethodOutcome create(T theResource, String theIfNoneExist, boolean thePerformIndexing);
DaoMethodOutcome delete(IdDt theResource);
DaoMethodOutcome delete(IIdType theResource);
DaoMethodOutcome deleteByUrl(String theString);
@ -56,11 +57,11 @@ public interface IFhirResourceDao<T extends IResource> extends IDao {
Class<T> getResourceType();
TagList getTags(IdDt theResourceId);
TagList getTags(IIdType theResourceId);
IBundleProvider history(Date theSince);
IBundleProvider history(IdDt theId, Date theSince);
IBundleProvider history(IIdType theId, Date theSince);
IBundleProvider history(Long theId, Date theSince);
@ -71,17 +72,17 @@ public interface IFhirResourceDao<T extends IResource> extends IDao {
* @throws ResourceNotFoundException
* If the ID is not known to the server
*/
T read(IdDt theId);
T read(IIdType theId);
BaseHasResource readEntity(IdDt theId);
BaseHasResource readEntity(IIdType theId);
/**
* @param theCheckForForcedId If true, this method should fail if the requested ID contains a numeric PID which exists, but is
* obscured by a "forced ID" so should not exist as far as the outside world is concerned.
*/
BaseHasResource readEntity(IdDt theId, boolean theCheckForForcedId);
BaseHasResource readEntity(IIdType theId, boolean theCheckForForcedId);
void removeTag(IdDt theId, TagTypeEnum theTagType, String theScheme, String theTerm);
void removeTag(IIdType theId, TagTypeEnum theTagType, String theScheme, String theTerm);
IBundleProvider search(Map<String, IQueryParameterType> theParams);
@ -114,15 +115,15 @@ public interface IFhirResourceDao<T extends IResource> extends IDao {
/**
* Not supported in DSTU1!
*/
MetaDt metaGetOperation(IdDt theId);
MetaDt metaGetOperation(IIdType theId);
/**
* Not supported in DSTU1!
*/
MetaDt metaDeleteOperation(IdDt theId1, MetaDt theMetaDel);
MetaDt metaDeleteOperation(IIdType theId1, MetaDt theMetaDel);
/**
* Not supported in DSTU1!
*/
MetaDt metaAddOperation(IdDt theId1, MetaDt theMetaAdd);
MetaDt metaAddOperation(IIdType theId1, MetaDt theMetaAdd);
}

View File

@ -24,38 +24,24 @@ import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.TagList;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
import ca.uhn.fhir.model.dstu.valueset.IssueSeverityEnum;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.annotation.Create;
import ca.uhn.fhir.rest.annotation.Delete;
import ca.uhn.fhir.rest.annotation.GetTags;
import ca.uhn.fhir.rest.annotation.History;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.Read;
import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.annotation.Since;
import ca.uhn.fhir.rest.annotation.Update;
import ca.uhn.fhir.rest.annotation.Validate;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.server.IBundleProvider;
import ca.uhn.fhir.rest.server.IResourceProvider;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
public abstract class BaseJpaResourceProvider<T extends IResource> extends BaseJpaProvider implements IResourceProvider {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BaseJpaResourceProvider.class);
private FhirContext myContext;
private IFhirResourceDao<T> myDao;
public BaseJpaResourceProvider() {
@ -138,19 +124,4 @@ public abstract class BaseJpaResourceProvider<T extends IResource> extends BaseJ
myDao = theDao;
}
@Validate
public MethodOutcome validate(HttpServletRequest theRequest, @ResourceParam T theResource) {
startRequest(theRequest);
try {
MethodOutcome retVal = new MethodOutcome();
retVal.setOperationOutcome(new OperationOutcome());
BaseIssue issue = retVal.getOperationOutcome().addIssue();
issue.getSeverityElement().setValue("information");
issue.setDetails("Resource validates successfully");
return retVal;
} finally {
endRequest(theRequest);
}
}
}

View File

@ -24,12 +24,15 @@ import javax.servlet.http.HttpServletRequest;
import ca.uhn.fhir.jpa.dao.IFhirResourceDao;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.annotation.Create;
import ca.uhn.fhir.rest.annotation.Delete;
import ca.uhn.fhir.rest.annotation.IdParam;
import ca.uhn.fhir.rest.annotation.ResourceParam;
import ca.uhn.fhir.rest.annotation.Update;
import ca.uhn.fhir.rest.annotation.Validate;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.server.exceptions.ResourceNotFoundException;
@ -80,4 +83,19 @@ public class JpaResourceProviderDstu1<T extends IResource> extends BaseJpaResour
}
}
@Validate
public MethodOutcome validate(HttpServletRequest theRequest, @ResourceParam T theResource) {
startRequest(theRequest);
try {
MethodOutcome retVal = new MethodOutcome();
retVal.setOperationOutcome(new OperationOutcome());
BaseIssue issue = ((OperationOutcome)retVal.getOperationOutcome()).addIssue();
issue.getSeverityElement().setValue("information");
issue.setDetails("Resource validates successfully (note that on this server, the DSTU1 endpoint validation only validates basic ability to parse the resource)");
return retVal;
} finally {
endRequest(theRequest);
}
}
}

View File

@ -153,6 +153,12 @@ public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResour
}
}
@Validate
public MethodOutcome validate(@ResourceParam T theResource, @ResourceParam String theRawResource, @ResourceParam EncodingEnum theEncoding, @Validate.Mode ValidationModeEnum theMode,
@Validate.Profile String theProfile) {
return validate(theResource, null, theRawResource, theEncoding, theMode, theProfile);
}
@Validate
public MethodOutcome validate(@ResourceParam T theResource, @IdParam IdDt theId, @ResourceParam String theRawResource, @ResourceParam EncodingEnum theEncoding, @Validate.Mode ValidationModeEnum theMode,
@Validate.Profile String theProfile) {
@ -177,7 +183,8 @@ public class JpaResourceProviderDstu2<T extends IResource> extends BaseJpaResour
validator.setValidateAgainstStandardSchema(true);
validator.setValidateAgainstStandardSchematron(true);
ValidationResult result = validator.validateWithResult(theResource);
for (BaseIssue next : result.getOperationOutcome().getIssue()) {
OperationOutcome operationOutcome = (OperationOutcome) result.getOperationOutcome();
for (BaseIssue next : operationOutcome.getIssue()) {
oo.getIssue().add((Issue) next);
}

View File

@ -6,6 +6,7 @@ import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
import org.hamcrest.core.StringContains;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@ -46,7 +47,7 @@ public class FhirResourceDaoDstu1Test extends BaseJpaTest {
Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
p.setId("Patient/" + methodName);
IdDt id = ourPatientDao.create(p).getId();
IIdType id = ourPatientDao.create(p).getId();
ourLog.info("Created patient, got it: {}", id);
p = new Patient();
@ -95,13 +96,13 @@ public class FhirResourceDaoDstu1Test extends BaseJpaTest {
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateRejectsIdWhichPointsToForcedId01");
p1.addName().addFamily("Tester").addGiven("testUpdateRejectsIdWhichPointsToForcedId01");
p1.setId("ABABA");
IdDt p1id = ourPatientDao.create(p1).getId();
IIdType p1id = ourPatientDao.create(p1).getId();
assertEquals("ABABA", p1id.getIdPart());
Patient p2 = new Patient();
p2.addIdentifier().setSystem("urn:system").setValue("testUpdateRejectsIdWhichPointsToForcedId02");
p2.addName().addFamily("Tester").addGiven("testUpdateRejectsIdWhichPointsToForcedId02");
IdDt p2id = ourPatientDao.create(p2).getId();
IIdType p2id = ourPatientDao.create(p2).getId();
long p1longId = p2id.getIdPartAsLong() - 1;
try {

View File

@ -1,22 +1,7 @@
package ca.uhn.fhir.jpa.dao;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsInRelativeOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.not;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.math.BigDecimal;
import java.util.ArrayList;
@ -30,6 +15,7 @@ import java.util.Set;
import org.apache.commons.lang3.RandomStringUtils;
import org.hamcrest.core.StringContains;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@ -113,10 +99,10 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
public void testQuestionnaireTitleGetsIndexed() {
Questionnaire q = new Questionnaire();
q.getGroup().setTitle("testQuestionnaireTitleGetsIndexedQ_TITLE");
IdDt qid1 = ourQuestionnaireDao.create(q).getId().toUnqualifiedVersionless();
IIdType qid1 = ourQuestionnaireDao.create(q).getId().toUnqualifiedVersionless();
q = new Questionnaire();
q.getGroup().setTitle("testQuestionnaireTitleGetsIndexedQ_NOTITLE");
IdDt qid2 = ourQuestionnaireDao.create(q).getId().toUnqualifiedVersionless();
IIdType qid2 = ourQuestionnaireDao.create(q).getId().toUnqualifiedVersionless();
IBundleProvider results = ourQuestionnaireDao.search("title", new StringParam("testQuestionnaireTitleGetsIndexedQ_TITLE"));
assertEquals(1, results.size());
@ -131,7 +117,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Observation o1 = new Observation();
o1.getCode().addCoding().setSystem("foo").setCode("testChoiceParam01");
o1.setValue(new CodeableConceptDt("testChoiceParam01CCS", "testChoiceParam01CCV"));
IdDt id1 = ourObservationDao.create(o1).getId();
IIdType id1 = ourObservationDao.create(o1).getId();
{
IBundleProvider found = ourObservationDao.search(Observation.SP_VALUE_CONCEPT, new TokenParam("testChoiceParam01CCS", "testChoiceParam01CCV"));
@ -145,7 +131,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Observation o2 = new Observation();
o2.getCode().addCoding().setSystem("foo").setCode("testChoiceParam02");
o2.setValue(new PeriodDt().setStart(new DateTimeDt("2001-01-01")).setEnd(new DateTimeDt("2001-01-03")));
IdDt id2 = ourObservationDao.create(o2).getId();
IIdType id2 = ourObservationDao.create(o2).getId();
{
IBundleProvider found = ourObservationDao.search(Observation.SP_VALUE_DATE, new DateParam("2001-01-02"));
@ -159,7 +145,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Observation o2 = new Observation();
o2.getCode().addCoding().setSystem("foo").setCode("testChoiceParamDateAlt02");
o2.setApplies(new DateTimeDt("2015-03-08T11:11:11"));
IdDt id2 = ourObservationDao.create(o2).getId();
IIdType id2 = ourObservationDao.create(o2).getId();
{
Set<Long> found = ourObservationDao.searchForIds(Observation.SP_DATE, new DateParam(">2001-01-02"));
@ -176,7 +162,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Observation o3 = new Observation();
o3.getCode().addCoding().setSystem("foo").setCode("testChoiceParam03");
o3.setValue(new QuantityDt(QuantityComparatorEnum.GREATERTHAN, 123.0, "foo", "bar").setCode("bar"));
IdDt id3 = ourObservationDao.create(o3).getId();
IIdType id3 = ourObservationDao.create(o3).getId();
{
IBundleProvider found = ourObservationDao.search(Observation.SP_VALUE_QUANTITY, new QuantityParam(">100", "foo", "bar"));
@ -205,7 +191,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Observation o4 = new Observation();
o4.getCode().addCoding().setSystem("foo").setCode("testChoiceParam04");
o4.setValue(new StringDt("testChoiceParam04Str"));
IdDt id4 = ourObservationDao.create(o4).getId();
IIdType id4 = ourObservationDao.create(o4).getId();
{
IBundleProvider found = ourObservationDao.search(Observation.SP_VALUE_STRING, new StringParam("testChoiceParam04Str"));
@ -249,7 +235,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
IdDt id = ourPatientDao.create(p).getId();
IIdType id = ourPatientDao.create(p).getId();
ourLog.info("Created patient, got it: {}", id);
p = new Patient();
@ -438,9 +424,9 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
public void testDeleteResource() {
int initialHistory = ourPatientDao.history(null).size();
IdDt id1;
IdDt id2;
IdDt id2b;
IIdType id1;
IIdType id2;
IIdType id2b;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
@ -502,7 +488,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().addFamily("Tester_testDeleteThenUndelete").addGiven("Joe");
IdDt id = ourPatientDao.create(patient).getId();
IIdType id = ourPatientDao.create(patient).getId();
assertThat(id.getValue(), endsWith("/_history/1"));
// should be ok
@ -522,11 +508,11 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().addFamily("Tester_testDeleteThenUndelete").addGiven("Joe");
patient.setId(id.toUnqualifiedVersionless());
IdDt id2 = ourPatientDao.update(patient).getId();
IIdType id2 = ourPatientDao.update(patient).getId();
assertThat(id2.getValue(), endsWith("/_history/3"));
IdDt gotId = ourPatientDao.read(id.toUnqualifiedVersionless()).getId();
IIdType gotId = ourPatientDao.read(id.toUnqualifiedVersionless()).getId();
assertEquals(id2, gotId);
}
@ -536,7 +522,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
IdDt id = ourPatientDao.create(p).getId();
IIdType id = ourPatientDao.create(p).getId();
ourLog.info("Created patient, got it: {}", id);
Bundle request = new Bundle();
@ -569,8 +555,8 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
@Test
public void testHistoryByForcedId() {
IdDt idv1;
IdDt idv2;
IIdType idv1;
IIdType idv2;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("testHistoryByForcedId");
@ -706,26 +692,26 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
public void testPersistResourceLink() {
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("testPersistResourceLink01");
IdDt patientId01 = ourPatientDao.create(patient).getId();
IIdType patientId01 = ourPatientDao.create(patient).getId();
Patient patient02 = new Patient();
patient02.addIdentifier().setSystem("urn:system").setValue("testPersistResourceLink02");
IdDt patientId02 = ourPatientDao.create(patient02).getId();
IIdType patientId02 = ourPatientDao.create(patient02).getId();
Observation obs01 = new Observation();
obs01.setApplies(new DateTimeDt(new Date()));
obs01.setSubject(new ResourceReferenceDt(patientId01));
IdDt obsId01 = ourObservationDao.create(obs01).getId();
IIdType obsId01 = ourObservationDao.create(obs01).getId();
Observation obs02 = new Observation();
obs02.setApplies(new DateTimeDt(new Date()));
obs02.setSubject(new ResourceReferenceDt(patientId02));
IdDt obsId02 = ourObservationDao.create(obs02).getId();
IIdType obsId02 = ourObservationDao.create(obs02).getId();
// Create another type, that shouldn't be returned
DiagnosticReport dr01 = new DiagnosticReport();
dr01.setSubject(new ResourceReferenceDt(patientId01));
IdDt drId01 = ourDiagnosticReportDao.create(dr01).getId();
IIdType drId01 = ourDiagnosticReportDao.create(dr01).getId();
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", new Object[] { patientId01, patientId02, obsId01, obsId02, drId01 });
@ -871,12 +857,12 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testReadVorcedIdVersionHistory01");
p1.setId("testReadVorcedIdVersionHistory");
IdDt p1id = ourPatientDao.update(p1).getId();
IIdType p1id = ourPatientDao.update(p1).getId();
assertEquals("testReadVorcedIdVersionHistory", p1id.getIdPart());
p1.addIdentifier().setSystem("urn:system").setValue("testReadVorcedIdVersionHistory02");
p1.setId(p1id);
IdDt p1idv2 = ourPatientDao.update(p1).getId();
IIdType p1idv2 = ourPatientDao.update(p1).getId();
assertEquals("testReadVorcedIdVersionHistory", p1idv2.getIdPart());
assertNotEquals(p1id.getValue(), p1idv2.getValue());
@ -894,7 +880,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
String methodName = "testReverseIncludes";
Organization org = new Organization();
org.setName("X" + methodName + "X");
IdDt orgId = ourOrganizationDao.create(org).getId();
IIdType orgId = ourOrganizationDao.create(org).getId();
Patient pat = new Patient();
pat.addName().addFamily("X" + methodName + "X");
@ -917,7 +903,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
deleteEverything();
String methodName = "testResourceInstanceMetaOperation";
IdDt id1, id2;
IIdType id1, id2;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue(methodName);
@ -1035,7 +1021,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
deleteEverything();
String methodName = "testResourceMetaOperation";
IdDt id1, id2;
IIdType id1, id2;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue(methodName);
@ -1172,13 +1158,13 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
@Test
public void testSearchByIdParam() {
IdDt id1;
IIdType id1;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
id1 = ourPatientDao.create(patient).getId();
}
IdDt id2;
IIdType id2;
{
Organization patient = new Organization();
patient.addIdentifier().setSystem("urn:system").setValue("001");
@ -1202,12 +1188,12 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Observation o1 = new Observation();
o1.getCode().addCoding().setSystem("foo").setCode("testSearchCompositeParamN01");
o1.setValue(new StringDt("testSearchCompositeParamS01"));
IdDt id1 = ourObservationDao.create(o1).getId();
IIdType id1 = ourObservationDao.create(o1).getId();
Observation o2 = new Observation();
o2.getCode().addCoding().setSystem("foo").setCode("testSearchCompositeParamN01");
o2.setValue(new StringDt("testSearchCompositeParamS02"));
IdDt id2 = ourObservationDao.create(o2).getId();
IIdType id2 = ourObservationDao.create(o2).getId();
{
TokenParam v0 = new TokenParam("foo", "testSearchCompositeParamN01");
@ -1232,12 +1218,12 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Observation o1 = new Observation();
o1.getCode().addCoding().setSystem("foo").setCode("testSearchCompositeParamDateN01");
o1.setValue(new PeriodDt().setStart(new DateTimeDt("2001-01-01T11:11:11")));
IdDt id1 = ourObservationDao.create(o1).getId().toUnqualifiedVersionless();
IIdType id1 = ourObservationDao.create(o1).getId().toUnqualifiedVersionless();
Observation o2 = new Observation();
o2.getCode().addCoding().setSystem("foo").setCode("testSearchCompositeParamDateN01");
o2.setValue(new PeriodDt().setStart(new DateTimeDt("2001-01-01T12:12:12")));
IdDt id2 = ourObservationDao.create(o2).getId().toUnqualifiedVersionless();
IIdType id2 = ourObservationDao.create(o2).getId().toUnqualifiedVersionless();
{
TokenParam v0 = new TokenParam("foo", "testSearchCompositeParamDateN01");
@ -1271,7 +1257,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
@Test
public void testSearchLanguageParam() {
IdDt id1;
IIdType id1;
{
Patient patient = new Patient();
patient.getLanguage().setValue("en_CA");
@ -1279,7 +1265,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
patient.addName().addFamily("testSearchLanguageParam").addGiven("Joe");
id1 = ourPatientDao.create(patient).getId();
}
IdDt id2;
IIdType id2;
{
Patient patient = new Patient();
patient.getLanguage().setValue("en_US");
@ -1318,14 +1304,14 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Thread.sleep(sleep);
DateTimeDt beforeAny = new DateTimeDt(new Date(), TemporalPrecisionEnum.MILLI);
IdDt id1a;
IIdType id1a;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().addFamily(methodName).addGiven("Joe");
id1a = ourPatientDao.create(patient).getId().toUnqualifiedVersionless();
}
IdDt id1b;
IIdType id1b;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("002");
@ -1337,7 +1323,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
DateTimeDt beforeR2 = new DateTimeDt(new Date(), TemporalPrecisionEnum.MILLI);
Thread.sleep(1100);
IdDt id2;
IIdType id2;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("002");
@ -1347,33 +1333,33 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
{
SearchParameterMap params = new SearchParameterMap();
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
assertThat(patients, hasItems(id1a, id1b, id2));
}
{
SearchParameterMap params = new SearchParameterMap();
params.setLastUpdated(new DateRangeParam(beforeAny, null));
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
assertThat(patients, hasItems(id1a, id1b, id2));
}
{
SearchParameterMap params = new SearchParameterMap();
params.setLastUpdated(new DateRangeParam(beforeR2, null));
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
assertThat(patients, hasItems(id2));
assertThat(patients, not(hasItems(id1a, id1b)));
}
{
SearchParameterMap params = new SearchParameterMap();
params.setLastUpdated(new DateRangeParam(beforeAny, beforeR2));
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
assertThat(patients.toString(), patients, not(hasItems(id2)));
assertThat(patients.toString(), patients, (hasItems(id1a, id1b)));
}
{
SearchParameterMap params = new SearchParameterMap();
params.setLastUpdated(new DateRangeParam(null, beforeR2));
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
assertThat(patients, (hasItems(id1a, id1b)));
assertThat(patients, not(hasItems(id2)));
}
@ -1381,7 +1367,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
@Test
public void testSearchNameParam() {
IdDt id1;
IIdType id1;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
@ -1433,12 +1419,12 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Encounter e1 = new Encounter();
e1.addIdentifier().setSystem("foo").setValue("testSearchNumberParam01");
e1.getLength().setSystem(BaseFhirDao.UCUM_NS).setCode("min").setValue(4.0 * 24 * 60);
IdDt id1 = ourEncounterDao.create(e1).getId();
IIdType id1 = ourEncounterDao.create(e1).getId();
Encounter e2 = new Encounter();
e2.addIdentifier().setSystem("foo").setValue("testSearchNumberParam02");
e2.getLength().setSystem(BaseFhirDao.UCUM_NS).setCode("year").setValue(2.0);
IdDt id2 = ourEncounterDao.create(e2).getId();
IIdType id2 = ourEncounterDao.create(e2).getId();
{
IBundleProvider found = ourEncounterDao.search(Encounter.SP_LENGTH, new NumberParam(">2"));
assertEquals(2, found.size());
@ -1460,27 +1446,27 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithChainXX");
patient.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithChain01");
IdDt patientId01 = ourPatientDao.create(patient).getId();
IIdType patientId01 = ourPatientDao.create(patient).getId();
Patient patient02 = new Patient();
patient02.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithChainXX");
patient02.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithChain02");
IdDt patientId02 = ourPatientDao.create(patient02).getId();
IIdType patientId02 = ourPatientDao.create(patient02).getId();
Observation obs01 = new Observation();
obs01.setApplies(new DateTimeDt(new Date()));
obs01.setSubject(new ResourceReferenceDt(patientId01));
IdDt obsId01 = ourObservationDao.create(obs01).getId();
IIdType obsId01 = ourObservationDao.create(obs01).getId();
Observation obs02 = new Observation();
obs02.setApplies(new DateTimeDt(new Date()));
obs02.setSubject(new ResourceReferenceDt(patientId02));
IdDt obsId02 = ourObservationDao.create(obs02).getId();
IIdType obsId02 = ourObservationDao.create(obs02).getId();
// Create another type, that shouldn't be returned
DiagnosticReport dr01 = new DiagnosticReport();
dr01.setSubject(new ResourceReferenceDt(patientId01));
IdDt drId01 = ourDiagnosticReportDao.create(dr01).getId();
IIdType drId01 = ourDiagnosticReportDao.create(dr01).getId();
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", new Object[] { patientId01, patientId02, obsId01, obsId02, drId01 });
@ -1513,21 +1499,21 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Patient patient = new Patient();
patient.addName().addFamily("testSearchResourceLinkWithChainWithMultipleTypes01");
patient.addName().addFamily("testSearchResourceLinkWithChainWithMultipleTypesXX");
IdDt patientId01 = ourPatientDao.create(patient).getId();
IIdType patientId01 = ourPatientDao.create(patient).getId();
Location loc01 = new Location();
loc01.getNameElement().setValue("testSearchResourceLinkWithChainWithMultipleTypes01");
IdDt locId01 = ourLocationDao.create(loc01).getId();
IIdType locId01 = ourLocationDao.create(loc01).getId();
Observation obs01 = new Observation();
obs01.setApplies(new DateTimeDt(new Date()));
obs01.setSubject(new ResourceReferenceDt(patientId01));
IdDt obsId01 = ourObservationDao.create(obs01).getId();
IIdType obsId01 = ourObservationDao.create(obs01).getId();
Observation obs02 = new Observation();
obs02.setApplies(new DateTimeDt(new Date()));
obs02.setSubject(new ResourceReferenceDt(locId01));
IdDt obsId02 = ourObservationDao.create(obs02).getId();
IIdType obsId02 = ourObservationDao.create(obs02).getId();
ourLog.info("P1[{}] L1[{}] Obs1[{}] Obs2[{}]", new Object[] { patientId01, locId01, obsId01, obsId02 });
@ -1552,28 +1538,28 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
patient.setId("testSearchResourceLinkWithTextLogicalId01");
patient.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithTextLogicalIdXX");
patient.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithTextLogicalId01");
IdDt patientId01 = ourPatientDao.update(patient).getId();
IIdType patientId01 = ourPatientDao.update(patient).getId();
Patient patient02 = new Patient();
patient02.setId("testSearchResourceLinkWithTextLogicalId02");
patient02.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithTextLogicalIdXX");
patient02.addIdentifier().setSystem("urn:system").setValue("testSearchResourceLinkWithTextLogicalId02");
IdDt patientId02 = ourPatientDao.update(patient02).getId();
IIdType patientId02 = ourPatientDao.update(patient02).getId();
Observation obs01 = new Observation();
obs01.setApplies(new DateTimeDt(new Date()));
obs01.setSubject(new ResourceReferenceDt(patientId01));
IdDt obsId01 = ourObservationDao.create(obs01).getId();
IIdType obsId01 = ourObservationDao.create(obs01).getId();
Observation obs02 = new Observation();
obs02.setApplies(new DateTimeDt(new Date()));
obs02.setSubject(new ResourceReferenceDt(patientId02));
IdDt obsId02 = ourObservationDao.create(obs02).getId();
IIdType obsId02 = ourObservationDao.create(obs02).getId();
// Create another type, that shouldn't be returned
DiagnosticReport dr01 = new DiagnosticReport();
dr01.setSubject(new ResourceReferenceDt(patientId01));
IdDt drId01 = ourDiagnosticReportDao.create(dr01).getId();
IIdType drId01 = ourDiagnosticReportDao.create(dr01).getId();
ourLog.info("P1[{}] P2[{}] O1[{}] O2[{}] D1[{}]", new Object[] { patientId01, patientId02, obsId01, obsId02, drId01 });
@ -1625,9 +1611,9 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
@Test
public void testSearchWithMissingString() {
IdDt orgId = ourOrganizationDao.create(new Organization()).getId();
IdDt notMissing;
IdDt missing;
IIdType orgId = ourOrganizationDao.create(new Organization()).getId();
IIdType notMissing;
IIdType missing;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
@ -1647,7 +1633,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
StringParam param = new StringParam();
param.setMissing(false);
params.put(Patient.SP_FAMILY, param);
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
assertThat(patients, not(containsInRelativeOrder(missing)));
assertThat(patients, containsInRelativeOrder(notMissing));
}
@ -1656,7 +1642,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
StringParam param = new StringParam();
param.setMissing(true);
params.put(Patient.SP_FAMILY, param);
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
assertThat(patients, containsInRelativeOrder(missing));
assertThat(patients, not(containsInRelativeOrder(notMissing)));
}
@ -1664,8 +1650,8 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
@Test
public void testSearchWithMissingQuantity() {
IdDt notMissing;
IdDt missing;
IIdType notMissing;
IIdType missing;
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("001");
@ -1683,7 +1669,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
QuantityParam param = new QuantityParam();
param.setMissing(false);
params.put(Observation.SP_VALUE_QUANTITY, param);
List<IdDt> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
List<IIdType> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
assertThat(patients, not(containsInRelativeOrder(missing)));
assertThat(patients, containsInRelativeOrder(notMissing));
}
@ -1692,7 +1678,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
QuantityParam param = new QuantityParam();
param.setMissing(true);
params.put(Observation.SP_VALUE_QUANTITY, param);
List<IdDt> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
List<IIdType> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
assertThat(patients, containsInRelativeOrder(missing));
assertThat(patients, not(containsInRelativeOrder(notMissing)));
}
@ -1700,8 +1686,8 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
@Test
public void testSearchWithToken() {
IdDt notMissing;
IdDt missing;
IIdType notMissing;
IIdType missing;
{
Observation obs = new Observation();
obs.addIdentifier().setSystem("urn:system").setValue("001");
@ -1719,7 +1705,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
TokenParam param = new TokenParam();
param.setMissing(false);
params.put(Observation.SP_CODE, param);
List<IdDt> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
List<IIdType> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
assertThat(patients, not(containsInRelativeOrder(missing)));
assertThat(patients, containsInRelativeOrder(notMissing));
}
@ -1728,7 +1714,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
TokenParam param = new TokenParam();
param.setMissing(true);
params.put(Observation.SP_CODE, param);
List<IdDt> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
List<IIdType> patients = toUnqualifiedVersionlessIds(ourObservationDao.search(params));
assertThat(patients, containsInRelativeOrder(missing));
assertThat(patients, not(containsInRelativeOrder(notMissing)));
}
@ -1736,9 +1722,9 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
@Test
public void testSearchWithMissingDate() {
IdDt orgId = ourOrganizationDao.create(new Organization()).getId();
IdDt notMissing;
IdDt missing;
IIdType orgId = ourOrganizationDao.create(new Organization()).getId();
IIdType notMissing;
IIdType missing;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
@ -1758,7 +1744,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
DateParam param = new DateParam();
param.setMissing(false);
params.put(Patient.SP_BIRTHDATE, param);
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
assertThat(patients, not(containsInRelativeOrder(missing)));
assertThat(patients, containsInRelativeOrder(notMissing));
}
@ -1767,7 +1753,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
DateParam param = new DateParam();
param.setMissing(true);
params.put(Patient.SP_BIRTHDATE, param);
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
assertThat(patients, containsInRelativeOrder(missing));
assertThat(patients, not(containsInRelativeOrder(notMissing)));
}
@ -1775,9 +1761,9 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
@Test
public void testSearchWithMissingReference() {
IdDt orgId = ourOrganizationDao.create(new Organization()).getId().toUnqualifiedVersionless();
IdDt notMissing;
IdDt missing;
IIdType orgId = ourOrganizationDao.create(new Organization()).getId().toUnqualifiedVersionless();
IIdType notMissing;
IIdType missing;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
@ -1797,7 +1783,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
ReferenceParam param = new ReferenceParam();
param.setMissing(false);
params.put(Patient.SP_ORGANIZATION, param);
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
assertThat(patients, not(containsInRelativeOrder(missing)));
assertThat(patients, containsInRelativeOrder(notMissing));
}
@ -1806,7 +1792,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
ReferenceParam param = new ReferenceParam();
param.setMissing(true);
params.put(Patient.SP_ORGANIZATION, param);
List<IdDt> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
List<IIdType> patients = toUnqualifiedVersionlessIds(ourPatientDao.search(params));
assertThat(patients, containsInRelativeOrder(missing));
assertThat(patients, not(containsInRelativeOrder(notMissing)));
assertThat(patients, not(containsInRelativeOrder(orgId)));
@ -1939,7 +1925,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
@Test
public void testSearchWithIncludes() {
IdDt parentOrgId;
IIdType parentOrgId;
{
Organization org = new Organization();
org.getNameElement().setValue("testSearchWithIncludes_O1Parent");
@ -1949,7 +1935,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Organization org = new Organization();
org.getNameElement().setValue("testSearchWithIncludes_O1");
org.setPartOf(new ResourceReferenceDt(parentOrgId));
IdDt orgId = ourOrganizationDao.create(org).getId();
IIdType orgId = ourOrganizationDao.create(org).getId();
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
@ -2028,7 +2014,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Organization org = new Organization();
org.setId("testSearchWithIncludesThatHaveTextId_id1");
org.getNameElement().setValue("testSearchWithIncludesThatHaveTextId_O1");
IdDt orgId = ourOrganizationDao.update(org).getId();
IIdType orgId = ourOrganizationDao.update(org).getId();
assertThat(orgId.getValue(), endsWith("Organization/testSearchWithIncludesThatHaveTextId_id1/_history/1"));
Patient patient = new Patient();
@ -2066,26 +2052,26 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
p.addIdentifier().setSystem("urn:system").setValue("testtestSortByDate");
p.addName().addFamily("testSortF1").addGiven("testSortG1");
p.setBirthDate(new DateDt("2001-01-01"));
IdDt id1 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
IIdType id1 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
// Create out of order
p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue("testtestSortByDate");
p.addName().addFamily("testSortF2").addGiven("testSortG2");
p.setBirthDate(new DateDt("2001-01-03"));
IdDt id3 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
IIdType id3 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue("testtestSortByDate");
p.addName().addFamily("testSortF3").addGiven("testSortG3");
p.setBirthDate(new DateDt("2001-01-02"));
IdDt id2 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
IIdType id2 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue("testtestSortByDate");
IdDt id4 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
IIdType id4 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
List<IdDt> actual;
List<IIdType> actual;
SearchParameterMap pm;
pm = new SearchParameterMap();
@ -2117,28 +2103,28 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
IdDt id1 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
IIdType id1 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
IdDt id2 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
IIdType id2 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
p = new Patient();
p.setId(methodName);
p.addIdentifier().setSystem("urn:system").setValue(methodName);
IdDt idMethodName = ourPatientDao.update(p).getId().toUnqualifiedVersionless();
IIdType idMethodName = ourPatientDao.update(p).getId().toUnqualifiedVersionless();
assertEquals(methodName, idMethodName.getIdPart());
p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
IdDt id3 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
IIdType id3 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
IdDt id4 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
IIdType id4 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
SearchParameterMap pm;
List<IdDt> actual;
List<IIdType> actual;
pm = new SearchParameterMap();
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", methodName));
@ -2167,25 +2153,25 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue("testSortByString");
p.addName().addFamily("testSortF1").addGiven("testSortG1");
IdDt id1 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
IIdType id1 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
// Create out of order
p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue("testSortByString");
p.addName().addFamily("testSortF3").addGiven("testSortG3");
IdDt id3 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
IIdType id3 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue("testSortByString");
p.addName().addFamily("testSortF2").addGiven("testSortG2");
IdDt id2 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
IIdType id2 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue("testSortByString");
IdDt id4 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
IIdType id4 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
SearchParameterMap pm;
List<IdDt> actual;
List<IIdType> actual;
pm = new SearchParameterMap();
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", "testSortByString"));
@ -2214,36 +2200,36 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
String methodName = "testSortByReference";
Organization o1 = new Organization();
IdDt oid1 = ourOrganizationDao.create(o1).getId().toUnqualifiedVersionless();
IIdType oid1 = ourOrganizationDao.create(o1).getId().toUnqualifiedVersionless();
Organization o2 = new Organization();
IdDt oid2 = ourOrganizationDao.create(o2).getId().toUnqualifiedVersionless();
IIdType oid2 = ourOrganizationDao.create(o2).getId().toUnqualifiedVersionless();
Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
p.addName().addFamily("testSortF1").addGiven("testSortG1");
p.getManagingOrganization().setReference(oid1);
IdDt id1 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
IIdType id1 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
p.addName().addFamily("testSortF2").addGiven("testSortG2");
p.getManagingOrganization().setReference(oid2);
IdDt id2 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
IIdType id2 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
p.addName().addFamily("testSortF3").addGiven("testSortG3");
p.getManagingOrganization().setReference(oid1);
IdDt id3 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
IIdType id3 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
p.getManagingOrganization().setReference(oid2);
IdDt id4 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
IIdType id4 = ourPatientDao.create(p).getId().toUnqualifiedVersionless();
SearchParameterMap pm;
List<IdDt> actual;
List<IIdType> actual;
pm = new SearchParameterMap();
pm.add(Patient.SP_IDENTIFIER, new TokenParam("urn:system", methodName));
@ -2274,13 +2260,13 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
public void testStoreUnversionedResources() {
Organization o1 = new Organization();
o1.getNameElement().setValue("AAA");
IdDt o1id = ourOrganizationDao.create(o1).getId();
IIdType o1id = ourOrganizationDao.create(o1).getId();
assertTrue(o1id.hasVersionIdPart());
Patient p1 = new Patient();
p1.addName().addFamily("AAAA");
p1.getManagingOrganization().setReference(o1id);
IdDt p1id = ourPatientDao.create(p1).getId();
IIdType p1id = ourPatientDao.create(p1).getId();
p1 = ourPatientDao.read(p1id);
@ -2296,7 +2282,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Organization org = new Organization();
org.setName("測試醫院");
org.addIdentifier().setSystem("urn:system").setValue("testStoreUtf8Characters_01");
IdDt orgId = ourOrganizationDao.create(org).getId();
IIdType orgId = ourOrganizationDao.create(org).getId();
Organization returned = ourOrganizationDao.read(orgId);
String val = ourFhirCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(returned);
@ -2357,7 +2343,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
ResourceMetadataKeyEnum.PROFILES.put(patient, profiles);
MethodOutcome outcome = ourPatientDao.create(patient);
IdDt patientId = outcome.getId();
IIdType patientId = outcome.getId();
assertNotNull(patientId);
assertFalse(patientId.isEmpty());
@ -2534,7 +2520,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
IdDt id = ourPatientDao.create(p).getId();
IIdType id = ourPatientDao.create(p).getId();
ourLog.info("Created patient, got it: {}", id);
p = new Patient();
@ -2560,7 +2546,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
p.addName().addFamily("Hello");
p.setId("Patient/" + methodName);
IdDt id = ourPatientDao.update(p).getId();
IIdType id = ourPatientDao.update(p).getId();
assertEquals("Patient/" + methodName, id.toUnqualifiedVersionless().getValue());
p = ourPatientDao.read(id);
@ -2587,7 +2573,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateMaintainsSearchParamsDstu2AAA");
p1.addName().addFamily("Tester").addGiven("testUpdateMaintainsSearchParamsDstu2AAA");
IdDt p1id = ourPatientDao.create(p1).getId();
IIdType p1id = ourPatientDao.create(p1).getId();
Patient p2 = new Patient();
p2.addIdentifier().setSystem("urn:system").setValue("testUpdateMaintainsSearchParamsDstu2BBB");
@ -2601,7 +2587,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
// Update the name
p1.getNameFirstRep().getGivenFirstRep().setValue("testUpdateMaintainsSearchParamsDstu2BBB");
MethodOutcome update2 = ourPatientDao.update(p1);
IdDt p1id2 = update2.getId();
IIdType p1id2 = update2.getId();
ids = ourPatientDao.searchForIds(Patient.SP_GIVEN, new StringDt("testUpdateMaintainsSearchParamsDstu2AAA"));
assertEquals(0, ids.size());
@ -2623,7 +2609,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateRejectsInvalidTypes");
p1.addName().addFamily("Tester").addGiven("testUpdateRejectsInvalidTypes");
IdDt p1id = ourPatientDao.create(p1).getId();
IIdType p1id = ourPatientDao.create(p1).getId();
Organization p2 = new Organization();
p2.getNameElement().setValue("testUpdateRejectsInvalidTypes");
@ -2664,10 +2650,10 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
return theSearch.getResources(0, theSearch.size());
}
private List<IdDt> toUnqualifiedVersionlessIds(IBundleProvider theFound) {
List<IdDt> retVal = new ArrayList<IdDt>();
private List<IIdType> toUnqualifiedVersionlessIds(IBundleProvider theFound) {
List<IIdType> retVal = new ArrayList<IIdType>();
for (IBaseResource next : theFound.getResources(0, theFound.size())) {
retVal.add((IdDt) next.getIdElement().toUnqualifiedVersionless());
retVal.add((IIdType) next.getIdElement().toUnqualifiedVersionless());
}
return retVal;
}
@ -2707,7 +2693,7 @@ public class FhirResourceDaoDstu2Test extends BaseJpaTest {
ourLog.info("Initial size: " + value.size());
for (IBaseResource next : value.getResources(0, value.size())) {
ourLog.info("Deleting: {}", next.getIdElement());
ourDeviceDao.delete((IdDt) next.getIdElement());
ourDeviceDao.delete((IIdType) next.getIdElement());
}
value = ourDeviceDao.search(new SearchParameterMap());

View File

@ -88,19 +88,19 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("testHistory");
patient.addName().addFamily("Tester").addGiven("Joe");
IdDt pid = ourPatientDao.create(patient).getId().toVersionless();
IIdType pid = ourPatientDao.create(patient).getId().toVersionless();
Thread.sleep(10);
patient.setId(pid);
IdDt newpid = ourPatientDao.update(patient).getId();
IIdType newpid = ourPatientDao.update(patient).getId();
Thread.sleep(10);
patient.setId(pid);
IdDt newpid2 = ourPatientDao.update(patient).getId();
IIdType newpid2 = ourPatientDao.update(patient).getId();
Thread.sleep(10);
patient.setId(pid);
IdDt newpid3 = ourPatientDao.update(patient).getId();
IIdType newpid3 = ourPatientDao.update(patient).getId();
IBundleProvider values = ourSystemDao.history(start);
assertEquals(4, values.size());
@ -113,7 +113,7 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
Location loc = new Location();
loc.getAddress().addLine("AAA");
IdDt lid = ourLocationDao.create(loc).getId();
IIdType lid = ourLocationDao.create(loc).getId();
Location loc2 = new Location();
loc2.getAddress().addLine("AAA");
@ -224,7 +224,7 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
Observation o1 = new Observation();
o1.getName().setText("testGetAllTags02");
ResourceMetadataKeyEnum.TAG_LIST.put(o1, tl2);
IdDt o1id = ourObservationDao.create(o1).getId();
IIdType o1id = ourObservationDao.create(o1).getId();
assertTrue(o1id.getVersionIdPart() != null);
TagList postSystemTl = ourSystemDao.getAllTags();
@ -241,7 +241,7 @@ public class FhirSystemDaoDstu1Test extends BaseJpaTest {
o1.getResourceMetadata().remove(ResourceMetadataKeyEnum.TAG_LIST);
o1.setId(o1id);
IdDt o1id2 = ourObservationDao.update(o1).getId();
IIdType o1id2 = ourObservationDao.update(o1).getId();
assertTrue(o1id2.getVersionIdPart() != null);
tags2 = ourObservationDao.getTags(o1id);

View File

@ -1,18 +1,7 @@
package ca.uhn.fhir.jpa.dao;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.emptyString;
import static org.hamcrest.Matchers.endsWith;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.io.InputStream;
import java.sql.SQLException;
@ -21,11 +10,11 @@ import java.util.List;
import org.apache.commons.io.IOUtils;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jmx.access.InvalidInvocationException;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.FhirVersionEnum;
@ -76,7 +65,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
assertEquals(0, published.size());
String methodName = "testSystemMetaOperation";
IdDt id1;
IIdType id1;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue(methodName);
@ -165,7 +154,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
p.setId("Patient/" + methodName);
IdDt id = ourPatientDao.update(p).getId();
IIdType id = ourPatientDao.update(p).getId();
ourLog.info("Created patient, got it: {}", id);
p = new Patient();
@ -205,7 +194,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
IdDt id = ourPatientDao.create(p).getId();
IIdType id = ourPatientDao.create(p).getId();
ourLog.info("Created patient, got it: {}", id);
p = new Patient();
@ -333,13 +322,13 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue(methodName);
IdDt id1 = ourPatientDao.create(p1).getId();
IIdType id1 = ourPatientDao.create(p1).getId();
ourLog.info("Created patient, got it: {}", id1);
Patient p2 = new Patient();
p2.addIdentifier().setSystem("urn:system").setValue(methodName);
p2.setId("Patient/" + methodName);
IdDt id2 = ourPatientDao.update(p2).getId();
IIdType id2 = ourPatientDao.update(p2).getId();
ourLog.info("Created patient, got it: {}", id2);
Bundle request = new Bundle();
@ -379,7 +368,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
IdDt id = ourPatientDao.create(p).getId();
IIdType id = ourPatientDao.create(p).getId();
ourLog.info("Created patient, got it: {}", id);
Bundle request = new Bundle();
@ -420,7 +409,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
IdDt id = ourPatientDao.create(p).getId();
IIdType id = ourPatientDao.create(p).getId();
ourLog.info("Created patient, got it: {}", id);
p = new Patient();
@ -466,7 +455,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
p.setId("Patient/" + methodName);
IdDt id = ourPatientDao.update(p).getId();
IIdType id = ourPatientDao.update(p).getId();
ourLog.info("Created patient, got it: {}", id);
Bundle request = new Bundle();
@ -531,14 +520,14 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
p.setId("Patient/" + methodName);
IdDt idv1 = ourPatientDao.update(p).getId();
IIdType idv1 = ourPatientDao.update(p).getId();
ourLog.info("Created patient, got id: {}", idv1);
p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
p.addName().addFamily("Family Name");
p.setId("Patient/" + methodName);
IdDt idv2 = ourPatientDao.update(p).getId();
IIdType idv2 = ourPatientDao.update(p).getId();
ourLog.info("Updated patient, got id: {}", idv2);
Bundle request = new Bundle();
@ -573,14 +562,14 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
p.setId("Patient/" + methodName);
IdDt idv1 = ourPatientDao.update(p).getId();
IIdType idv1 = ourPatientDao.update(p).getId();
ourLog.info("Created patient, got id: {}", idv1);
p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
p.addName().addFamily("Family Name");
p.setId("Patient/" + methodName);
IdDt idv2 = ourPatientDao.update(p).getId();
IIdType idv2 = ourPatientDao.update(p).getId();
ourLog.info("Updated patient, got id: {}", idv2);
Bundle request = new Bundle();
@ -619,14 +608,14 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
p.setId("Patient/" + methodName);
IdDt idv1 = ourPatientDao.update(p).getId();
IIdType idv1 = ourPatientDao.update(p).getId();
ourLog.info("Created patient, got id: {}", idv1);
p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
p.addName().addFamily("Family Name");
p.setId("Patient/" + methodName);
IdDt idv2 = ourPatientDao.update(p).getId();
IIdType idv2 = ourPatientDao.update(p).getId();
ourLog.info("Updated patient, got id: {}", idv2);
Bundle request = new Bundle();
@ -664,7 +653,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
IdDt id = ourPatientDao.create(p).getId();
IIdType id = ourPatientDao.create(p).getId();
ourLog.info("Created patient, got it: {}", id);
p = new Patient();
@ -705,7 +694,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
IdDt id = ourPatientDao.create(p).getId();
IIdType id = ourPatientDao.create(p).getId();
ourLog.info("Created patient, got it: {}", id);
p = new Patient();
@ -739,7 +728,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
Patient p = new Patient();
p.addName().addFamily("Hello");
IdDt id = ourPatientDao.create(p).getId();
IIdType id = ourPatientDao.create(p).getId();
p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
@ -778,7 +767,7 @@ public class FhirSystemDaoDstu2Test extends BaseJpaTest {
Patient p = new Patient();
p.addIdentifier().setSystem("urn:system").setValue(methodName);
p.setId("Patient/" + methodName);
IdDt id = ourPatientDao.update(p).getId();
IIdType id = ourPatientDao.update(p).getId();
ourLog.info("Created patient, got it: {}", id);
p = new Patient();

View File

@ -11,6 +11,7 @@ import org.apache.commons.io.IOUtils;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@ -111,7 +112,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testCreateWithId01");
IdDt p1Id = ourClient.create().resource(p1).withId("testCreateWithId").execute().getId();
IIdType p1Id = ourClient.create().resource(p1).withId("testCreateWithId").execute().getId();
assertThat(p1Id.getValue(), containsString("Patient/testCreateWithId/_history"));
@ -143,12 +144,12 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
Location l1 = new Location();
l1.getNameElement().setValue("testDeepChainingL1");
IdDt l1id = ourClient.create().resource(l1).execute().getId();
IIdType l1id = ourClient.create().resource(l1).execute().getId();
Location l2 = new Location();
l2.getNameElement().setValue("testDeepChainingL2");
l2.getPartOf().setReference(l1id.toVersionless().toUnqualified());
IdDt l2id = ourClient.create().resource(l2).execute().getId();
IIdType l2id = ourClient.create().resource(l2).execute().getId();
Encounter e1 = new Encounter();
e1.addIdentifier().setSystem("urn:foo").setValue("testDeepChainingE1");
@ -157,7 +158,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
ca.uhn.fhir.model.dstu.resource.Encounter.Location location = e1.addLocation();
location.getLocation().setReference(l2id.toUnqualifiedVersionless());
location.setPeriod(new PeriodDt().setStartWithSecondsPrecision(new Date()).setEndWithSecondsPrecision(new Date()));
IdDt e1id = ourClient.create().resource(e1).execute().getId();
IIdType e1id = ourClient.create().resource(e1).execute().getId();
//@formatter:off
Bundle res = ourClient.search()
@ -257,9 +258,9 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
p1.getText().getDiv().setValueAsString("<div>HELLO WORLD</div>");
p1.addIdentifier().setSystem("urn:system").setValue("testSaveAndRetrieveExistingNarrative01");
IdDt newId = ourClient.create().resource(p1).execute().getId();
IIdType newId = ourClient.create().resource(p1).execute().getId();
Patient actual = ourClient.read(Patient.class, newId);
Patient actual = ourClient.read(Patient.class, (IdDt)newId);
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">HELLO WORLD</div>", actual.getText().getDiv().getValueAsString());
}
@ -273,9 +274,9 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
p1.getManagingOrganization().setResource(o1);
IdDt newId = ourClient.create().resource(p1).execute().getId();
IIdType newId = ourClient.create().resource(p1).execute().getId();
Patient actual = ourClient.read(Patient.class, newId);
Patient actual = ourClient.read(Patient.class, (IdDt)newId);
assertEquals(1, actual.getContained().getContainedResources().size());
assertThat(actual.getText().getDiv().getValueAsString(), containsString("<td>Identifier</td><td>testSaveAndRetrieveWithContained01</td>"));
@ -289,9 +290,9 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01");
IdDt newId = ourClient.create().resource(p1).execute().getId();
IIdType newId = ourClient.create().resource(p1).execute().getId();
Patient actual = ourClient.read(Patient.class, newId);
Patient actual = ourClient.read(Patient.class, (IdDt)newId);
assertThat(actual.getText().getDiv().getValueAsString(), containsString("<td>Identifier</td><td>testSearchByResourceChain01</td>"));
}
@ -303,7 +304,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByIdentifier01");
p1.addName().addFamily("testSearchByIdentifierFamily01").addGiven("testSearchByIdentifierGiven01");
IdDt p1Id = ourClient.create().resource(p1).execute().getId();
IIdType p1Id = ourClient.create().resource(p1).execute().getId();
Patient p2 = new Patient();
p2.addIdentifier().setSystem("urn:system").setValue("testSearchByIdentifier02");
@ -321,7 +322,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
Patient p1 = new Patient();
p1.addIdentifier().setValue("testSearchByIdentifierWithoutSystem01");
IdDt p1Id = ourClient.create().resource(p1).execute().getId();
IIdType p1Id = ourClient.create().resource(p1).execute().getId();
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode(null, "testSearchByIdentifierWithoutSystem01")).encodedJson().prettyPrint().execute();
assertEquals(1, actual.size());
@ -336,13 +337,13 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
Organization o1 = new Organization();
o1.setName("testSearchByResourceChainName01");
IdDt o1id = ourClient.create().resource(o1).execute().getId();
IIdType o1id = ourClient.create().resource(o1).execute().getId();
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01");
p1.addName().addFamily("testSearchByResourceChainFamily01").addGiven("testSearchByResourceChainGiven01");
p1.setManagingOrganization(new ResourceReferenceDt(o1id));
IdDt p1Id = ourClient.create().resource(p1).execute().getId();
IIdType p1Id = ourClient.create().resource(p1).execute().getId();
//@formatter:off
Bundle actual = ourClient.search()
@ -368,7 +369,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
public void testSearchWithInclude() throws Exception {
Organization org = new Organization();
org.addIdentifier().setSystem("urn:system").setValue( "testSearchWithInclude01");
IdDt orgId = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId();
IIdType orgId = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId();
Patient pat = new Patient();
pat.addIdentifier().setSystem("urn:system").setValue("testSearchWithInclude02");
@ -401,7 +402,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
Organization org = new Organization();
org.setName("測試醫院");
org.addIdentifier().setSystem("urn:system").setValue("testStoreUtf8Characters_01");
IdDt orgId = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId();
IIdType orgId = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId();
// Read back directly from the DAO
{
@ -412,7 +413,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
}
// Read back through the HTTP API
{
Organization returned = ourClient.read(Organization.class, orgId);
Organization returned = ourClient.read(Organization.class, (IdDt)orgId);
String val = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(returned);
ourLog.info(val);
assertThat(val, containsString("<name value=\"測試醫院\"/>"));
@ -444,7 +445,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateRejectsInvalidTypes");
p1.addName().addFamily("Tester").addGiven("testUpdateRejectsInvalidTypes");
IdDt p1id = ourClient.create().resource(p1).execute().getId();
IIdType p1id = ourClient.create().resource(p1).execute().getId();
Organization p2 = new Organization();
p2.getNameElement().setValue("testUpdateRejectsInvalidTypes");
@ -472,7 +473,7 @@ public class ResourceProviderDstu1Test extends BaseJpaTest {
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateWithClientSuppliedIdWhichDoesntExist");
MethodOutcome outcome = ourClient.update().resource(p1).withId("testUpdateWithClientSuppliedIdWhichDoesntExist").execute();
assertEquals(true, outcome.getCreated().booleanValue());
IdDt p1Id = outcome.getId();
IIdType p1Id = outcome.getId();
assertThat(p1Id.getValue(), containsString("Patient/testUpdateWithClientSuppliedIdWhichDoesntExist/_history"));

View File

@ -1,12 +1,6 @@
package ca.uhn.fhir.jpa.provider;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsInRelativeOrder;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.Matchers.startsWith;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.io.BufferedReader;
@ -38,6 +32,7 @@ import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
@ -77,6 +72,7 @@ import ca.uhn.fhir.model.primitive.DateTimeDt;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.primitive.UnsignedIntDt;
import ca.uhn.fhir.model.primitive.UriDt;
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.narrative.DefaultThymeleafNarrativeGenerator;
@ -141,7 +137,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
IGenericClient client = ourClient;
String resBody = IOUtils.toString(ResourceProviderDstu2Test.class.getResource("/document-father.json"));
IdDt id = client.create().resource(resBody).execute().getId();
IIdType id = client.create().resource(resBody).execute().getId();
ourLog.info("Created: {}", id);
@ -246,12 +242,12 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
Location l1 = new Location();
l1.getNameElement().setValue("testDeepChainingL1");
IdDt l1id = ourClient.create().resource(l1).execute().getId();
IIdType l1id = ourClient.create().resource(l1).execute().getId();
Location l2 = new Location();
l2.getNameElement().setValue("testDeepChainingL2");
l2.getPartOf().setReference(l1id.toVersionless().toUnqualified());
IdDt l2id = ourClient.create().resource(l2).execute().getId();
IIdType l2id = ourClient.create().resource(l2).execute().getId();
Encounter e1 = new Encounter();
e1.addIdentifier().setSystem("urn:foo").setValue("testDeepChainingE1");
@ -260,7 +256,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
ca.uhn.fhir.model.dstu2.resource.Encounter.Location location = e1.addLocation();
location.getLocation().setReference(l2id.toUnqualifiedVersionless());
location.setPeriod(new PeriodDt().setStartWithSecondsPrecision(new Date()).setEndWithSecondsPrecision(new Date()));
IdDt e1id = ourClient.create().resource(e1).execute().getId();
IIdType e1id = ourClient.create().resource(e1).execute().getId();
//@formatter:off
Bundle res = ourClient.search()
@ -542,30 +538,30 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
Organization org1 = new Organization();
org1.setName(methodName + "1");
IdDt orgId1 = ourClient.create().resource(org1).execute().getId();
IIdType orgId1 = ourClient.create().resource(org1).execute().getId();
Patient p = new Patient();
p.addName().addFamily(methodName);
p.getManagingOrganization().setReference(orgId1);
IdDt patientId = ourClient.create().resource(p).execute().getId();
IIdType patientId = ourClient.create().resource(p).execute().getId();
Organization org2 = new Organization();
org2.setName(methodName + "1");
IdDt orgId2 = ourClient.create().resource(org2).execute().getId();
IIdType orgId2 = ourClient.create().resource(org2).execute().getId();
Device dev = new Device();
dev.setModel(methodName);
dev.getOwner().setReference(orgId2);
IdDt devId = ourClient.create().resource(dev).execute().getId();
IIdType devId = ourClient.create().resource(dev).execute().getId();
Observation obs = new Observation();
obs.getSubject().setReference(patientId);
obs.getDevice().setReference(devId);
IdDt obsId = ourClient.create().resource(obs).execute().getId();
IIdType obsId = ourClient.create().resource(obs).execute().getId();
Encounter enc = new Encounter();
enc.getPatient().setReference(patientId);
IdDt encId = ourClient.create().resource(enc).execute().getId();
IIdType encId = ourClient.create().resource(enc).execute().getId();
Parameters output = ourClient.operation().onInstance(patientId).named("everything").withNoParameters(Parameters.class).execute();
ca.uhn.fhir.model.dstu2.resource.Bundle b = (ca.uhn.fhir.model.dstu2.resource.Bundle) output.getParameterFirstRep().getResource();
@ -636,9 +632,9 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
p1.getText().getDiv().setValueAsString("<div>HELLO WORLD</div>");
p1.addIdentifier().setSystem("urn:system").setValue("testSaveAndRetrieveExistingNarrative01");
IdDt newId = ourClient.create().resource(p1).execute().getId();
IIdType newId = ourClient.create().resource(p1).execute().getId();
Patient actual = ourClient.read(Patient.class, newId);
Patient actual = ourClient.read(Patient.class, (UriDt)newId);
assertEquals("<div xmlns=\"http://www.w3.org/1999/xhtml\">HELLO WORLD</div>", actual.getText().getDiv().getValueAsString());
}
@ -652,9 +648,9 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
p1.getManagingOrganization().setResource(o1);
IdDt newId = ourClient.create().resource(p1).execute().getId();
IIdType newId = ourClient.create().resource(p1).execute().getId();
Patient actual = ourClient.read(Patient.class, newId);
Patient actual = ourClient.read(Patient.class, (UriDt)newId);
assertEquals(1, actual.getContained().getContainedResources().size());
assertThat(actual.getText().getDiv().getValueAsString(), containsString("<td>Identifier</td><td>testSaveAndRetrieveWithContained01</td>"));
@ -668,7 +664,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01");
IdDt newId = ourClient.create().resource(p1).execute().getId();
IdDt newId = (IdDt) ourClient.create().resource(p1).execute().getId();
Patient actual = ourClient.read(Patient.class, newId);
assertThat(actual.getText().getDiv().getValueAsString(), containsString("<td>Identifier</td><td>testSearchByResourceChain01</td>"));
@ -696,7 +692,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByIdentifier01");
p1.addName().addFamily("testSearchByIdentifierFamily01").addGiven("testSearchByIdentifierGiven01");
IdDt p1Id = ourClient.create().resource(p1).execute().getId();
IdDt p1Id = (IdDt) ourClient.create().resource(p1).execute().getId();
Patient p2 = new Patient();
p2.addIdentifier().setSystem("urn:system").setValue("testSearchByIdentifier02");
@ -715,7 +711,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
Patient p1 = new Patient();
p1.addIdentifier().setValue("testSearchByIdentifierWithoutSystem01");
IdDt p1Id = ourClient.create().resource(p1).execute().getId();
IdDt p1Id = (IdDt) ourClient.create().resource(p1).execute().getId();
Bundle actual = ourClient.search().forResource(Patient.class).where(Patient.IDENTIFIER.exactly().systemAndCode(null, "testSearchByIdentifierWithoutSystem01")).encodedJson().prettyPrint()
.execute();
@ -731,13 +727,13 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
Organization o1 = new Organization();
o1.setName("testSearchByResourceChainName01");
IdDt o1id = ourClient.create().resource(o1).execute().getId();
IdDt o1id = (IdDt) ourClient.create().resource(o1).execute().getId();
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testSearchByResourceChain01");
p1.addName().addFamily("testSearchByResourceChainFamily01").addGiven("testSearchByResourceChainGiven01");
p1.setManagingOrganization(new ResourceReferenceDt(o1id));
IdDt p1Id = ourClient.create().resource(p1).execute().getId();
IdDt p1Id = (IdDt) ourClient.create().resource(p1).execute().getId();
//@formatter:off
Bundle actual = ourClient.search()
@ -763,7 +759,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
public void testSearchWithInclude() throws Exception {
Organization org = new Organization();
org.addIdentifier().setSystem("urn:system:rpdstu2").setValue("testSearchWithInclude01");
IdDt orgId = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId();
IdDt orgId = (IdDt) ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId();
Patient pat = new Patient();
pat.addIdentifier().setSystem("urn:system:rpdstu2").setValue("testSearchWithInclude02");
@ -827,12 +823,12 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
String methodName = "testSearchWithMissing";
Organization org = new Organization();
IdDt deletedIdMissingTrue = ourClient.create().resource(org).execute().getId().toUnqualifiedVersionless();
IdDt deletedIdMissingTrue = (IdDt) ourClient.create().resource(org).execute().getId().toUnqualifiedVersionless();
ourClient.delete().resourceById(deletedIdMissingTrue).execute();
org = new Organization();
org.setName("Help I'm a Bug");
IdDt deletedIdMissingFalse = ourClient.create().resource(org).execute().getId().toUnqualifiedVersionless();
IdDt deletedIdMissingFalse = (IdDt) ourClient.create().resource(org).execute().getId().toUnqualifiedVersionless();
ourClient.delete().resourceById(deletedIdMissingFalse).execute();
List<IResource> resources = new ArrayList<IResource>();
@ -846,11 +842,11 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
org = new Organization();
org.addIdentifier().setSystem("urn:system:rpdstu2").setValue(methodName + "01");
org.setName(methodName + "name");
IdDt orgNotMissing = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId().toUnqualifiedVersionless();
IdDt orgNotMissing = (IdDt) ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId().toUnqualifiedVersionless();
org = new Organization();
org.addIdentifier().setSystem("urn:system:rpdstu2").setValue(methodName + "01");
IdDt orgMissing = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId().toUnqualifiedVersionless();
IdDt orgMissing = (IdDt) ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId().toUnqualifiedVersionless();
{
//@formatter:off
@ -896,7 +892,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
Organization org = new Organization();
org.setName("測試醫院");
org.addIdentifier().setSystem("urn:system").setValue("testStoreUtf8Characters_01");
IdDt orgId = ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId();
IdDt orgId = (IdDt) ourClient.create().resource(org).prettyPrint().encodedXml().execute().getId();
// Read back directly from the DAO
{
@ -939,7 +935,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
Patient p1 = new Patient();
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateRejectsInvalidTypes");
p1.addName().addFamily("Tester").addGiven("testUpdateRejectsInvalidTypes");
IdDt p1id = ourClient.create().resource(p1).execute().getId();
IdDt p1id = (IdDt) ourClient.create().resource(p1).execute().getId();
Organization p2 = new Organization();
p2.getNameElement().setValue("testUpdateRejectsInvalidTypes");
@ -1002,7 +998,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
p1.addIdentifier().setSystem("urn:system").setValue("testUpdateWithClientSuppliedIdWhichDoesntExistRpDstu2");
MethodOutcome outcome = ourClient.update().resource(p1).withId("testUpdateWithClientSuppliedIdWhichDoesntExistRpDstu2").execute();
assertEquals(true, outcome.getCreated().booleanValue());
IdDt p1Id = outcome.getId();
IdDt p1Id = (IdDt) outcome.getId();
assertThat(p1Id.getValue(), containsString("Patient/testUpdateWithClientSuppliedIdWhichDoesntExistRpDstu2/_history"));
@ -1040,6 +1036,33 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
}
}
@Test
public void testValidateResourceWithId() throws IOException {
Patient patient = new Patient();
patient.addName().addGiven("James");
patient.setBirthDate(new DateDt("2011-02-02"));
Parameters input = new Parameters();
input.addParameter().setName("resource").setResource(patient);
String inputStr = ourCtx.newXmlParser().encodeResourceToString(input);
ourLog.info(inputStr);
HttpPost post = new HttpPost(ourServerBase + "/Patient/123/$validate");
post.setEntity(new StringEntity(inputStr, ContentType.create(Constants.CT_FHIR_XML, "UTF-8")));
CloseableHttpResponse response = ourHttpClient.execute(post);
try {
String resp = IOUtils.toString(response.getEntity().getContent());
ourLog.info(resp);
assertEquals(200, response.getStatusLine().getStatusCode());
} finally {
IOUtils.closeQuietly(response.getEntity().getContent());
response.close();
}
}
@Test
public void testValidateResourceHuge() throws IOException {
@ -1148,14 +1171,14 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("001");
patient.addName().addFamily(methodName).addGiven("Joe");
id1a = ourClient.create().resource(patient).execute().getId().toUnqualifiedVersionless();
id1a = (IdDt) ourClient.create().resource(patient).execute().getId().toUnqualifiedVersionless();
}
IdDt id1b;
{
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("002");
patient.addName().addFamily(methodName + "XXXX").addGiven("Joe");
id1b = ourClient.create().resource(patient).execute().getId().toUnqualifiedVersionless();
id1b = (IdDt) ourClient.create().resource(patient).execute().getId().toUnqualifiedVersionless();
}
Thread.sleep(1100);
@ -1167,7 +1190,7 @@ public class ResourceProviderDstu2Test extends BaseJpaTest {
Patient patient = new Patient();
patient.addIdentifier().setSystem("urn:system").setValue("002");
patient.addName().addFamily(methodName).addGiven("John");
id2 = ourClient.create().resource(patient).execute().getId().toUnqualifiedVersionless();
id2 = (IdDt) ourClient.create().resource(patient).execute().getId().toUnqualifiedVersionless();
}
{

View File

@ -46,7 +46,7 @@ public class ResourceProviderMultiVersionTest extends BaseJpaTest {
p.addIdentifier("urn:MultiFhirVersionTest", "testSubmitPatient01");
p.addUndeclaredExtension(false, "http://foo#ext1", new StringDt("The value"));
p.getGender().setValueAsEnum(AdministrativeGenderCodesEnum.M);
IdDt id = ourClientDstu1.create().resource(p).execute().getId();
IdDt id = (IdDt) ourClientDstu1.create().resource(p).execute().getId();
// Read back as DSTU1
Patient patDstu1 = ourClientDstu1.read(Patient.class, id);
@ -76,7 +76,7 @@ public class ResourceProviderMultiVersionTest extends BaseJpaTest {
p.addIdentifier().setSystem("urn:MultiFhirVersionTest").setValue("testSubmitPatientDstu201");
p.addUndeclaredExtension(false, "http://foo#ext1", new StringDt("The value"));
p.setGender(AdministrativeGenderEnum.MALE);
IdDt id = ourClientDstu2.create().resource(p).execute().getId();
IdDt id = (IdDt) ourClientDstu2.create().resource(p).execute().getId();
// Read back as DSTU1
Patient patDstu1 = ourClientDstu1.read(Patient.class, id);
@ -105,7 +105,7 @@ public class ResourceProviderMultiVersionTest extends BaseJpaTest {
public void testUnknownResourceType() {
ca.uhn.fhir.model.dstu2.resource.Patient p = new ca.uhn.fhir.model.dstu2.resource.Patient();
p.addIdentifier().setSystem("urn:MultiFhirVersionTest").setValue("testUnknownResourceType01");
IdDt id = ourClientDstu2.create().resource(p).execute().getId();
IdDt id = (IdDt) ourClientDstu2.create().resource(p).execute().getId();
PaymentNotice s = new PaymentNotice();
s.addIdentifier().setSystem("urn:MultiFhirVersionTest").setValue("testUnknownResourceType02");

View File

@ -55,7 +55,7 @@ public class UhnFhirTestApp {
Organization o1 = new Organization();
o1.getName().setValue("Some Org");
MethodOutcome create = client.create(o1);
IdDt orgId = create.getId();
IdDt orgId = (IdDt) create.getId();
Patient p1 = new Patient();
p1.addIdentifier("foo:bar", "12345");

View File

@ -25,6 +25,7 @@ import static org.apache.commons.lang3.StringUtils.*;
import java.io.InputStream;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
@ -34,6 +35,7 @@ import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.text.WordUtils;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import ca.uhn.fhir.context.BaseRuntimeChildDefinition;
import ca.uhn.fhir.context.BaseRuntimeDeclaredChildDefinition;
@ -60,6 +62,7 @@ import ca.uhn.fhir.model.api.ICompositeDatatype;
import ca.uhn.fhir.model.api.IFhirVersion;
import ca.uhn.fhir.model.api.IPrimitiveDatatype;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.api.annotation.Child;
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
@ -85,7 +88,8 @@ import ca.uhn.fhir.rest.server.provider.ServerProfileProvider;
public class FhirDstu1 implements IFhirVersion {
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(FhirDstu1.class);
// private Map<RuntimeChildDeclaredExtensionDefinition, String> myExtensionDefToCode = new HashMap<RuntimeChildDeclaredExtensionDefinition, String>();
// private Map<RuntimeChildDeclaredExtensionDefinition, String> myExtensionDefToCode = new
// HashMap<RuntimeChildDeclaredExtensionDefinition, String>();
private String myId;
@Override
@ -93,6 +97,11 @@ public class FhirDstu1 implements IFhirVersion {
return new ServerConformanceProvider(theServer);
}
@Override
public IResourceProvider createServerProfilesProvider(RestfulServer theRestfulServer) {
return new ServerProfileProvider(theRestfulServer);
}
private void fillBasics(StructureElement theElement, BaseRuntimeElementDefinition<?> def, LinkedList<String> path, BaseRuntimeDeclaredChildDefinition theChild) {
if (path.isEmpty()) {
path.add(def.getName());
@ -234,8 +243,7 @@ public class FhirDstu1 implements IFhirVersion {
// ignore
} else if (child instanceof RuntimeChildDeclaredExtensionDefinition) {
throw new IllegalStateException("Unexpected child type: " + child.getClass().getCanonicalName());
} else if (child instanceof RuntimeChildCompositeDatatypeDefinition || child instanceof RuntimeChildPrimitiveDatatypeDefinition || child instanceof RuntimeChildChoiceDefinition
|| child instanceof RuntimeChildResourceDefinition) {
} else if (child instanceof RuntimeChildCompositeDatatypeDefinition || child instanceof RuntimeChildPrimitiveDatatypeDefinition || child instanceof RuntimeChildChoiceDefinition || child instanceof RuntimeChildResourceDefinition) {
Iterator<String> childNamesIter = child.getValidChildNames().iterator();
String nextName = childNamesIter.next();
BaseRuntimeElementDefinition<?> nextDef = child.getChildByName(nextName);
@ -295,6 +303,53 @@ public class FhirDstu1 implements IFhirVersion {
return retVal;
}
@Override
public Class<? extends BaseContainedDt> getContainedType() {
return ContainedDt.class;
}
@Override
public InputStream getFhirVersionPropertiesFile() {
InputStream str = FhirDstu1.class.getResourceAsStream("/ca/uhn/fhir/model/dstu/fhirversion.properties");
if (str == null) {
str = FhirDstu1.class.getResourceAsStream("ca/uhn/fhir/model/dstu/fhirversion.properties");
}
if (str == null) {
throw new ConfigurationException("Can not find model property file on classpath: " + "/ca/uhn/fhir/model/dstu/model.properties");
}
return str;
}
@Override
public IPrimitiveType<Date> getLastUpdated(IBaseResource theResource) {
return ResourceMetadataKeyEnum.UPDATED.get((IResource) theResource);
}
@Override
public String getPathToSchemaDefinitions() {
return "/ca/uhn/fhir/model/dstu/schema";
}
@Override
public Class<? extends BaseResourceReferenceDt> getResourceReferenceType() {
return ResourceReferenceDt.class;
}
@Override
public FhirVersionEnum getVersion() {
return FhirVersionEnum.DSTU1;
}
@Override
public IVersionSpecificBundleFactory newBundleFactory(FhirContext theContext) {
return new Dstu1BundleFactory(theContext);
}
@Override
public BaseCodingDt newCodingDt() {
return new CodingDt();
}
private Map<RuntimeChildDeclaredExtensionDefinition, String> scanForExtensions(Profile theProfile, BaseRuntimeElementDefinition<?> def, Map<RuntimeChildDeclaredExtensionDefinition, String> theExtensionDefToCode) {
BaseRuntimeElementCompositeDefinition<?> cdef = ((BaseRuntimeElementCompositeDefinition<?>) def);
@ -339,57 +394,8 @@ public class FhirDstu1 implements IFhirVersion {
}
}
return theExtensionDefToCode;
}
@Override
public IResourceProvider createServerProfilesProvider(RestfulServer theRestfulServer) {
return new ServerProfileProvider(theRestfulServer);
}
@Override
public FhirVersionEnum getVersion() {
return FhirVersionEnum.DSTU1;
}
@Override
public InputStream getFhirVersionPropertiesFile() {
InputStream str = FhirDstu1.class.getResourceAsStream("/ca/uhn/fhir/model/dstu/fhirversion.properties");
if (str == null) {
str = FhirDstu1.class.getResourceAsStream("ca/uhn/fhir/model/dstu/fhirversion.properties");
}
if (str == null) {
throw new ConfigurationException("Can not find model property file on classpath: " + "/ca/uhn/fhir/model/dstu/model.properties");
}
return str;
}
@Override
public String getPathToSchemaDefinitions() {
return "ca/uhn/fhir/model/dstu/schema";
}
@Override
public Class<? extends BaseResourceReferenceDt> getResourceReferenceType() {
return ResourceReferenceDt.class;
}
@Override
public Class<? extends BaseContainedDt> getContainedType() {
return ContainedDt.class;
}
@Override
public BaseCodingDt newCodingDt() {
return new CodingDt();
}
@Override
public IVersionSpecificBundleFactory newBundleFactory(FhirContext theContext) {
return new Dstu1BundleFactory(theContext);
}
}

View File

@ -38,6 +38,8 @@ package ca.uhn.fhir.model.dstu.composite;
import java.util.List;
import org.hl7.fhir.instance.model.api.IIdType;
import ca.uhn.fhir.model.api.ICompositeDatatype;
import ca.uhn.fhir.model.api.IElement;
import ca.uhn.fhir.model.api.IResource;
@ -110,7 +112,7 @@ public class ResourceReferenceDt
* @param theResourceId
* The reference itself
*/
public ResourceReferenceDt(IdDt theResourceId) {
public ResourceReferenceDt(IIdType theResourceId) {
setReference(theResourceId);
}

View File

@ -245,7 +245,7 @@ public class ClientDstu1Test {
assertEquals(HttpDelete.class, capt.getValue().getClass());
assertEquals("http://foo/Patient/1234", capt.getValue().getURI().toString());
assertEquals("Hello", response.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue());
assertEquals("Hello", ((OperationOutcome)response.getOperationOutcome()).getIssueFirstRep().getDetailsElement().getValue());
}
@Test

View File

@ -1155,7 +1155,7 @@ public class RestfulServerMethodTest {
public MethodOutcome deletePatient(@IdParam IdDt theId) {
MethodOutcome retVal = new MethodOutcome();
retVal.setOperationOutcome(new OperationOutcome());
retVal.getOperationOutcome().addIssue().setDetails(theId.getValue());
((OperationOutcome)retVal.getOperationOutcome()).addIssue().setDetails(theId.getValue());
return retVal;
}

View File

@ -1,5 +1,17 @@
package ca.uhn.fhir.validation;
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Locale;
import org.apache.commons.io.IOUtils;
import org.hamcrest.core.StringContains;
import org.junit.BeforeClass;
import org.junit.Test;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.api.Bundle;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
@ -7,23 +19,6 @@ import ca.uhn.fhir.model.dstu.resource.Patient;
import ca.uhn.fhir.model.dstu.valueset.ContactSystemEnum;
import ca.uhn.fhir.model.primitive.DateTimeDt;
import org.apache.commons.io.IOUtils;
import org.hamcrest.core.StringContains;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Locale;
import static org.hamcrest.Matchers.containsString;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public class ResourceValidatorTest {
private static FhirContext ourCtx = FhirContext.forDstu1();
@ -46,9 +41,10 @@ public class ResourceValidatorTest {
val.validate(p);
fail();
} catch (ValidationFailureException e) {
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome()));
assertEquals(1, e.getOperationOutcome().getIssue().size());
assertThat(e.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue(), containsString("cvc-complex-type.2.4.a"));
OperationOutcome outcome = (OperationOutcome) e.getOperationOutcome();
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(outcome));
assertEquals(1, outcome.getIssue().size());
assertThat(outcome.getIssueFirstRep().getDetailsElement().getValue(), containsString("cvc-complex-type.2.4.a"));
}
}
@ -91,7 +87,7 @@ public class ResourceValidatorTest {
String resultString = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(result.getOperationOutcome());
ourLog.info(resultString);
assertEquals(2, result.getOperationOutcome().getIssue().size());
assertEquals(2, ((OperationOutcome)result.getOperationOutcome()).getIssue().size());
assertThat(resultString, StringContains.containsString("cvc-datatype-valid.1.2.3"));
}
@ -111,9 +107,10 @@ public class ResourceValidatorTest {
val.validate(b);
fail();
} catch (ValidationFailureException e) {
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome()));
assertEquals(1, e.getOperationOutcome().getIssue().size());
assertThat(e.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue(), containsString("Inv-2:"));
OperationOutcome outcome = (OperationOutcome) e.getOperationOutcome();
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(outcome));
assertEquals(1, outcome.getIssue().size());
assertThat(outcome.getIssueFirstRep().getDetailsElement().getValue(), containsString("Inv-2:"));
}
}

View File

@ -1,7 +1,9 @@
package ca.uhn.fhir.validation;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
import ca.uhn.fhir.model.dstu.resource.OperationOutcome;
import org.junit.Test;
import java.util.List;
@ -15,46 +17,48 @@ import static org.junit.Assert.assertTrue;
public class ValidationResultDstu1Test {
@Test
public void isSuccessful_IsTrueForNullOperationOutcome() {
ValidationResult result = ValidationResult.valueOf(null);
assertTrue(result.isSuccessful());
}
private static final FhirContext ourCtx = FhirContext.forDstu1();
@Test
public void isSuccessful_IsTrueForNoIssues() {
OperationOutcome operationOutcome = new OperationOutcome();
// make sure a non-null ID doesn't cause the validation result to be a fail
operationOutcome.setId(UUID.randomUUID().toString());
ValidationResult result = ValidationResult.valueOf(operationOutcome);
assertTrue(result.isSuccessful());
}
@Test
public void isSuccessful_FalseForIssues() {
OperationOutcome operationOutcome = new OperationOutcome();
OperationOutcome.Issue issue = operationOutcome.addIssue();
String errorMessage = "There was a validation problem";
issue.setDetails(errorMessage);
ValidationResult result = ValidationResult.valueOf(ourCtx, operationOutcome);
assertFalse(result.isSuccessful());
List<? extends BaseIssue> issues = ((OperationOutcome) result.getOperationOutcome()).getIssue();
assertEquals(1, issues.size());
assertEquals(errorMessage, issues.get(0).getDetailsElement().getValue());
@Test
public void isSuccessful_FalseForIssues() {
OperationOutcome operationOutcome = new OperationOutcome();
OperationOutcome.Issue issue = operationOutcome.addIssue();
String errorMessage = "There was a validation problem";
issue.setDetails(errorMessage);
ValidationResult result = ValidationResult.valueOf(operationOutcome);
assertFalse(result.isSuccessful());
List<? extends BaseIssue> issues = result.getOperationOutcome().getIssue();
assertEquals(1, issues.size());
assertEquals(errorMessage, issues.get(0).getDetailsElement().getValue());
assertThat("ValidationResult#toString should contain the issue description", result.toString(), containsString(errorMessage));
}
assertThat("ValidationResult#toString should contain the issue description", result.toString(), containsString(errorMessage));
}
@Test
public void isSuccessful_IsTrueForNoIssues() {
OperationOutcome operationOutcome = new OperationOutcome();
// make sure a non-null ID doesn't cause the validation result to be a fail
operationOutcome.setId(UUID.randomUUID().toString());
ValidationResult result = ValidationResult.valueOf(ourCtx, operationOutcome);
assertTrue(result.isSuccessful());
}
/*
Test for https://github.com/jamesagnew/hapi-fhir/issues/51
*/
@Test
public void toString_ShouldNotCauseResultToBecomeFailure() {
OperationOutcome operationOutcome = new OperationOutcome();
ValidationResult result = ValidationResult.valueOf(operationOutcome);
assertEquals(true, result.isSuccessful());
// need to call toString to make sure any unwanted side effects are generated
@SuppressWarnings("UnusedDeclaration") String unused = result.toString();
assertEquals(true, result.isSuccessful());
}
@Test
public void isSuccessful_IsTrueForNullOperationOutcome() {
ValidationResult result = ValidationResult.valueOf(ourCtx, null);
assertTrue(result.isSuccessful());
}
/*
* Test for https://github.com/jamesagnew/hapi-fhir/issues/51
*/
@Test
public void toString_ShouldNotCauseResultToBecomeFailure() {
OperationOutcome operationOutcome = new OperationOutcome();
ValidationResult result = ValidationResult.valueOf(ourCtx, operationOutcome);
assertEquals(true, result.isSuccessful());
// need to call toString to make sure any unwanted side effects are generated
result.toString();
assertEquals(true, result.isSuccessful());
}
}

View File

@ -21,8 +21,11 @@ package ca.uhn.fhir.model.dstu2;
*/
import java.io.InputStream;
import java.util.Date;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
@ -30,6 +33,7 @@ import ca.uhn.fhir.context.FhirVersionEnum;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.model.api.IFhirVersion;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.base.composite.BaseCodingDt;
import ca.uhn.fhir.model.base.composite.BaseContainedDt;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
@ -54,6 +58,11 @@ public class FhirDstu2 implements IFhirVersion {
return new ServerConformanceProvider(theServer);
}
@Override
public IResourceProvider createServerProfilesProvider(RestfulServer theRestfulServer) {
return new ServerProfileProvider(theRestfulServer);
}
@Override
public IResource generateProfile(RuntimeResourceDefinition theRuntimeResourceDefinition, String theServerBase) {
StructureDefinition retVal = new StructureDefinition();
@ -70,13 +79,8 @@ public class FhirDstu2 implements IFhirVersion {
}
@Override
public IResourceProvider createServerProfilesProvider(RestfulServer theRestfulServer) {
return new ServerProfileProvider(theRestfulServer);
}
@Override
public FhirVersionEnum getVersion() {
return FhirVersionEnum.DSTU2;
public Class<? extends BaseContainedDt> getContainedType() {
return ContainedDt.class;
}
@Override
@ -91,9 +95,14 @@ public class FhirDstu2 implements IFhirVersion {
return str;
}
@Override
public IPrimitiveType<Date> getLastUpdated(IBaseResource theResource) {
return ResourceMetadataKeyEnum.UPDATED.get((IResource) theResource);
}
@Override
public String getPathToSchemaDefinitions() {
return "ca/uhn/fhir/model/dstu2/schema";
return "/ca/uhn/fhir/model/dstu2/schema";
}
@Override
@ -102,13 +111,8 @@ public class FhirDstu2 implements IFhirVersion {
}
@Override
public Class<? extends BaseContainedDt> getContainedType() {
return ContainedDt.class;
}
@Override
public BaseCodingDt newCodingDt() {
return new CodingDt();
public FhirVersionEnum getVersion() {
return FhirVersionEnum.DSTU2;
}
@Override
@ -116,5 +120,9 @@ public class FhirDstu2 implements IFhirVersion {
return new Dstu2BundleFactory(theContext);
}
@Override
public BaseCodingDt newCodingDt() {
return new CodingDt();
}
}

View File

@ -38,6 +38,8 @@ package ca.uhn.fhir.model.dstu2.composite;
import java.util.List;
import org.hl7.fhir.instance.model.api.IIdType;
import ca.uhn.fhir.model.api.ICompositeDatatype;
import ca.uhn.fhir.model.api.IElement;
import ca.uhn.fhir.model.api.IResource;
@ -114,6 +116,17 @@ public class ResourceReferenceDt
setReference(theResourceId);
}
/**
* Constructor which accepts a reference directly (this can be an ID, a partial/relative URL or a complete/absolute
* URL)
*
* @param theResourceId
* The reference itself
*/
public ResourceReferenceDt(IIdType theResourceId) {
setReference(theResourceId);
}
@Child(name="reference", type=IdDt.class, order=0, min=0, max=1)
@Description(
shortDefinition="Relative, internal or absolute URL reference",

View File

@ -24,23 +24,22 @@ import static org.apache.commons.lang3.StringUtils.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.rest.server.*;
import ca.uhn.fhir.util.ResourceReferenceInfo;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.api.ResourceMetadataKeyEnum;
import ca.uhn.fhir.model.base.composite.BaseResourceReferenceDt;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome;
@ -53,7 +52,17 @@ import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.valueset.BundleEntrySearchModeEnum;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.server.AddProfileTagEnum;
import ca.uhn.fhir.rest.server.BundleInclusionRule;
import ca.uhn.fhir.rest.server.Constants;
import ca.uhn.fhir.rest.server.EncodingEnum;
import ca.uhn.fhir.rest.server.IBundleProvider;
import ca.uhn.fhir.rest.server.IPagingProvider;
import ca.uhn.fhir.rest.server.IVersionSpecificBundleFactory;
import ca.uhn.fhir.rest.server.RestfulServer;
import ca.uhn.fhir.rest.server.RestfulServerUtils;
import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
import ca.uhn.fhir.util.ResourceReferenceInfo;
public class Dstu2BundleFactory implements IVersionSpecificBundleFactory {
@ -159,14 +168,14 @@ public class Dstu2BundleFactory implements IVersionSpecificBundleFactory {
}
@Override
public void addRootPropertiesToBundle(String theAuthor, String theServerBase, String theCompleteUrl, Integer theTotalResults, BundleTypeEnum theBundleType, InstantDt theLastUpdated) {
public void addRootPropertiesToBundle(String theAuthor, String theServerBase, String theCompleteUrl, Integer theTotalResults, BundleTypeEnum theBundleType, IPrimitiveType<Date> theLastUpdated) {
if (myBundle.getId().isEmpty()) {
myBundle.setId(UUID.randomUUID().toString());
}
if (ResourceMetadataKeyEnum.UPDATED.get(myBundle) == null) {
ResourceMetadataKeyEnum.UPDATED.put(myBundle, theLastUpdated);
ResourceMetadataKeyEnum.UPDATED.put(myBundle, (InstantDt) theLastUpdated);
}
if (!hasLink(Constants.LINK_SELF, myBundle) && isNotBlank(theCompleteUrl)) {

View File

@ -27,6 +27,7 @@ import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicStatusLine;
import org.hl7.fhir.instance.model.api.IBaseBundle;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.junit.Before;
import org.junit.BeforeClass;
@ -1174,10 +1175,14 @@ public class GenericClientDstu2Test {
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>", extractBody(capt, idx));
assertNotNull(response.getOperationOutcome());
assertEquals("FOOBAR", response.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue());
assertEquals("FOOBAR", toOo(response.getOperationOutcome()).getIssueFirstRep().getDetailsElement().getValue());
idx++;
}
private OperationOutcome toOo(IBaseOperationOutcome theOperationOutcome) {
return (OperationOutcome) theOperationOutcome;
}
@Test
public void testValidateFluent() throws Exception {
@ -1209,7 +1214,7 @@ public class GenericClientDstu2Test {
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>", extractBody(capt, idx));
assertNotNull(response.getOperationOutcome());
assertEquals("FOOBAR", response.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue());
assertEquals("FOOBAR", toOo(response.getOperationOutcome()).getIssueFirstRep().getDetailsElement().getValue());
idx++;
response = client.validate().resource(ourCtx.newXmlParser().encodeResourceToString(p)).execute();
@ -1217,7 +1222,7 @@ public class GenericClientDstu2Test {
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
assertEquals("<Parameters xmlns=\"http://hl7.org/fhir\"><parameter><name value=\"resource\"/><resource><Patient xmlns=\"http://hl7.org/fhir\"><name><given value=\"GIVEN\"/></name></Patient></resource></parameter></Parameters>", extractBody(capt, idx));
assertNotNull(response.getOperationOutcome());
assertEquals("FOOBAR", response.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue());
assertEquals("FOOBAR", toOo(response.getOperationOutcome()).getIssueFirstRep().getDetailsElement().getValue());
idx++;
response = client.validate().resource(ourCtx.newJsonParser().encodeResourceToString(p)).execute();
@ -1225,7 +1230,7 @@ public class GenericClientDstu2Test {
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
assertEquals("{\"resourceType\":\"Parameters\",\"parameter\":[{\"name\":\"resource\",\"resource\":{\"resourceType\":\"Patient\",\"name\":[{\"given\":[\"GIVEN\"]}]}}]}", extractBody(capt, idx));
assertNotNull(response.getOperationOutcome());
assertEquals("FOOBAR", response.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue());
assertEquals("FOOBAR", toOo(response.getOperationOutcome()).getIssueFirstRep().getDetailsElement().getValue());
idx++;
response = client.validate().resource(ourCtx.newJsonParser().encodeResourceToString(p)).prettyPrint().execute();
@ -1233,7 +1238,7 @@ public class GenericClientDstu2Test {
assertEquals("POST", capt.getAllValues().get(idx).getRequestLine().getMethod());
assertThat(extractBody(capt, idx), containsString("\"resourceType\":\"Parameters\",\n"));
assertNotNull(response.getOperationOutcome());
assertEquals("FOOBAR", response.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue());
assertEquals("FOOBAR", toOo(response.getOperationOutcome()).getIssueFirstRep().getDetailsElement().getValue());
idx++;
}

View File

@ -43,13 +43,13 @@ import ca.uhn.fhir.util.PortUtil;
/**
* Created by dsotnikov on 2/25/2014.
*/
public class BinaryTestDstu2 {
public class BinaryDstu2Test {
private static CloseableHttpClient ourClient;
private static FhirContext ourCtx = FhirContext.forDstu2();
private static Binary ourLast;
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BinaryTestDstu2.class);
private static final org.slf4j.Logger ourLog = org.slf4j.LoggerFactory.getLogger(BinaryDstu2Test.class);
private static int ourPort;

View File

@ -235,11 +235,13 @@ public class IncludeDstu2Test {
@Test
public void testTwoInclude() throws Exception {
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?name=Hello&_include=foo&_include=bar");
HttpGet httpGet = new HttpGet("http://localhost:" + ourPort + "/Patient?name=Hello&_include=foo&_include=bar&_pretty=true");
HttpResponse status = ourClient.execute(httpGet);
String responseContent = IOUtils.toString(status.getEntity().getContent());
IOUtils.closeQuietly(status.getEntity().getContent());
ourLog.info(responseContent);
assertEquals(200, status.getStatusLine().getStatusCode());
Bundle bundle = ourCtx.newXmlParser().parseBundle(responseContent);
assertEquals(1, bundle.size());

View File

@ -14,6 +14,7 @@ import java.util.Locale;
import org.apache.commons.io.IOUtils;
import org.hamcrest.core.StringContains;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.junit.Test;
import ca.uhn.fhir.context.FhirContext;
@ -65,7 +66,7 @@ public class ResourceValidatorDstu2Test {
String resultString = ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(result.getOperationOutcome());
ourLog.info(resultString);
assertEquals(2, result.getOperationOutcome().getIssue().size());
assertEquals(2, ((OperationOutcome)result.getOperationOutcome()).getIssue().size());
assertThat(resultString, StringContains.containsString("2000-15-31"));
}
@ -156,9 +157,10 @@ public class ResourceValidatorDstu2Test {
val.validate(p);
fail();
} catch (ValidationFailureException e) {
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(e.getOperationOutcome()));
assertEquals(1, e.getOperationOutcome().getIssue().size());
assertThat(e.getOperationOutcome().getIssueFirstRep().getDetailsElement().getValue(), containsString("cvc-complex-type"));
OperationOutcome operationOutcome = (OperationOutcome) e.getOperationOutcome();
ourLog.info(ourCtx.newXmlParser().setPrettyPrint(true).encodeResourceToString(operationOutcome));
assertEquals(1, operationOutcome.getIssue().size());
assertThat(operationOutcome.getIssueFirstRep().getDetailsElement().getValue(), containsString("cvc-complex-type"));
}
}

View File

@ -11,14 +11,17 @@ import java.util.UUID;
import org.junit.Test;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.model.base.resource.BaseOperationOutcome.BaseIssue;
import ca.uhn.fhir.model.dstu2.resource.OperationOutcome;
public class ValidationResultDstu2Test {
private static final FhirContext ourCtx = FhirContext.forDstu2();
@Test
public void isSuccessful_IsTrueForNullOperationOutcome() {
ValidationResult result = ValidationResult.valueOf(null);
ValidationResult result = ValidationResult.valueOf(ourCtx, null);
assertTrue(result.isSuccessful());
}
@ -27,7 +30,7 @@ public class ValidationResultDstu2Test {
OperationOutcome operationOutcome = new OperationOutcome();
// make sure a non-null ID doesn't cause the validation result to be a fail
operationOutcome.setId(UUID.randomUUID().toString());
ValidationResult result = ValidationResult.valueOf(operationOutcome);
ValidationResult result = ValidationResult.valueOf(ourCtx, operationOutcome);
assertTrue(result.isSuccessful());
}
@ -37,9 +40,9 @@ public class ValidationResultDstu2Test {
OperationOutcome.Issue issue = operationOutcome.addIssue();
String errorMessage = "There was a validation problem";
issue.setDetails(errorMessage);
ValidationResult result = ValidationResult.valueOf(operationOutcome);
ValidationResult result = ValidationResult.valueOf(ourCtx, operationOutcome);
assertFalse(result.isSuccessful());
List<? extends BaseIssue> issues = result.getOperationOutcome().getIssue();
List<? extends BaseIssue> issues = ((OperationOutcome)result.getOperationOutcome()).getIssue();
assertEquals(1, issues.size());
assertEquals(errorMessage, issues.get(0).getDetailsElement().getValue());
@ -52,7 +55,7 @@ public class ValidationResultDstu2Test {
@Test
public void toString_ShouldNotCauseResultToBecomeFailure() {
OperationOutcome operationOutcome = new OperationOutcome();
ValidationResult result = ValidationResult.valueOf(operationOutcome);
ValidationResult result = ValidationResult.valueOf(ourCtx, operationOutcome);
assertEquals(true, result.isSuccessful());
// need to call toString to make sure any unwanted side effects are generated
@SuppressWarnings("UnusedDeclaration") String unused = result.toString();

View File

@ -23,6 +23,8 @@ package ca.uhn.fhir.rest.server.provider.dstu2hl7org;
import static org.apache.commons.lang3.StringUtils.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@ -43,11 +45,11 @@ import org.hl7.fhir.instance.model.api.IBaseReference;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IDomainResource;
import org.hl7.fhir.instance.model.api.IIdType;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.model.api.Include;
import ca.uhn.fhir.model.primitive.InstantDt;
import ca.uhn.fhir.model.valueset.BundleTypeEnum;
import ca.uhn.fhir.rest.server.AddProfileTagEnum;
import ca.uhn.fhir.rest.server.BundleInclusionRule;
@ -85,14 +87,18 @@ public class Dstu2Hl7OrgBundleFactory implements IVersionSpecificBundleFactory {
}
}
for (IBaseResource nextBaseRes : theResult) {
if (!(nextBaseRes instanceof IDomainResource)) {
continue;
for (IBaseResource next : theResult) {
List<? extends IAnyResource> contained;
if (next instanceof IDomainResource) {
IDomainResource nextDomain = (IDomainResource) next;
contained = nextDomain.getContained();
} else {
contained = Collections.emptyList();
}
IDomainResource next = (IDomainResource) nextBaseRes;
Set<String> containedIds = new HashSet<String>();
for (IAnyResource nextContained : next.getContained()) {
for (IAnyResource nextContained : contained) {
if (nextContained.getId().isEmpty() == false) {
containedIds.add(nextContained.getIdElement().getValue());
}
@ -157,9 +163,9 @@ public class Dstu2Hl7OrgBundleFactory implements IVersionSpecificBundleFactory {
}
@Override
public void addRootPropertiesToBundle(String theAuthor, String theServerBase, String theCompleteUrl, Integer theTotalResults, BundleTypeEnum theBundleType, InstantDt theLastUpdated) {
public void addRootPropertiesToBundle(String theAuthor, String theServerBase, String theCompleteUrl, Integer theTotalResults, BundleTypeEnum theBundleType, IPrimitiveType<Date> theLastUpdated) {
if (myBundle.getId().isEmpty()) {
if (isBlank(myBundle.getId())) {
myBundle.setId(UUID.randomUUID().toString());
}
@ -203,9 +209,12 @@ public class Dstu2Hl7OrgBundleFactory implements IVersionSpecificBundleFactory {
List<IBaseResource> resourceList;
if (theServer.getPagingProvider() == null) {
numToReturn = theResult.size();
resourceList = theResult.getResources(0, numToReturn);
RestfulServerUtils.validateResourceListNotNull(resourceList);
if (numToReturn == 0) {
resourceList = Collections.emptyList();
} else {
resourceList = theResult.getResources(0, numToReturn);
RestfulServerUtils.validateResourceListNotNull(resourceList);
}
} else {
IPagingProvider pagingProvider = theServer.getPagingProvider();
if (theLimit == null) {

View File

@ -22,12 +22,16 @@ package org.hl7.fhir.instance;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import org.apache.commons.lang3.StringUtils;
import org.hl7.fhir.instance.conf.ServerConformanceProvider;
import org.hl7.fhir.instance.conf.ServerProfileProvider;
import org.hl7.fhir.instance.model.Reference;
import org.hl7.fhir.instance.model.Resource;
import org.hl7.fhir.instance.model.StructureDefinition;
import org.hl7.fhir.instance.model.api.IBaseResource;
import org.hl7.fhir.instance.model.api.IPrimitiveType;
import ca.uhn.fhir.context.ConfigurationException;
import ca.uhn.fhir.context.FhirContext;
@ -89,7 +93,7 @@ public class FhirDstu2Hl7Org implements IFhirVersion {
@Override
public String getPathToSchemaDefinitions() {
return "ca/uhn/fhir/model/dstu2/schema";
return "/org/hl7/fhir/instance/model/schema";
}
@Override
@ -113,4 +117,9 @@ public class FhirDstu2Hl7Org implements IFhirVersion {
return new Dstu2Hl7OrgBundleFactory(theContext);
}
@Override
public IPrimitiveType<Date> getLastUpdated(IBaseResource theResource) {
return ((Resource)theResource).getMeta().getLastUpdatedElement();
}
}

View File

@ -2,7 +2,7 @@ package org.hl7.fhir.instance.conf;
/*
* #%L
* HAPI FHIR Structures - HL7.org DSTU2
* HAPI FHIR Structures - DSTU2 (FHIR v0.5.0)
* %%
* Copyright (C) 2014 - 2015 University Health Network
* %%
@ -20,12 +20,18 @@ package org.hl7.fhir.instance.conf;
* #L%
*/
import static org.apache.commons.lang3.StringUtils.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import javax.servlet.http.HttpServletRequest;
@ -39,18 +45,20 @@ import org.hl7.fhir.instance.model.Conformance.ResourceInteractionComponent;
import org.hl7.fhir.instance.model.Conformance.RestfulConformanceMode;
import org.hl7.fhir.instance.model.Conformance.SystemRestfulInteraction;
import org.hl7.fhir.instance.model.Conformance.TypeRestfulInteraction;
import org.hl7.fhir.instance.model.DateTimeType;
import org.hl7.fhir.instance.model.ResourceType;
import org.hl7.fhir.instance.model.Enumerations.ConformanceResourceStatus;
import org.hl7.fhir.instance.model.OperationDefinition;
import org.hl7.fhir.instance.model.OperationDefinition.OperationDefinitionParameterComponent;
import org.hl7.fhir.instance.model.OperationDefinition.OperationParameterUse;
import ca.uhn.fhir.context.RuntimeResourceDefinition;
import ca.uhn.fhir.context.RuntimeSearchParam;
import ca.uhn.fhir.model.api.IResource;
import ca.uhn.fhir.model.primitive.DateTimeDt;
import ca.uhn.fhir.model.primitive.IdDt;
import ca.uhn.fhir.rest.annotation.Metadata;
import ca.uhn.fhir.rest.method.BaseMethodBinding;
import ca.uhn.fhir.rest.method.DynamicSearchMethodBinding;
import ca.uhn.fhir.rest.method.IParameter;
import ca.uhn.fhir.rest.method.OperationMethodBinding;
import ca.uhn.fhir.rest.method.OperationParameter;
import ca.uhn.fhir.rest.method.SearchMethodBinding;
import ca.uhn.fhir.rest.method.SearchParameter;
import ca.uhn.fhir.rest.server.Constants;
@ -63,8 +71,10 @@ import ca.uhn.fhir.rest.server.exceptions.InternalErrorException;
* Server FHIR Provider which serves the conformance statement for a RESTful server implementation
*
* <p>
* Note: This class is safe to extend, but it is important to note that the same instance of {@link Conformance} is always returned unless {@link #setCache(boolean)} is called with a value of
* <code>false</code>. This means that if you are adding anything to the returned conformance instance on each call you should call <code>setCache(false)</code> in your provider constructor.
* Note: This class is safe to extend, but it is important to note that the same instance of {@link Conformance} is
* always returned unless {@link #setCache(boolean)} is called with a value of <code>false</code>. This means that if
* you are adding anything to the returned conformance instance on each call you should call
* <code>setCache(false)</code> in your provider constructor.
* </p>
*/
public class ServerConformanceProvider implements IServerConformanceProvider<Conformance> {
@ -79,8 +89,9 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
}
/**
* Gets the value of the "publisher" that will be placed in the generated conformance statement. As this is a mandatory element, the value should not be null (although this is not enforced). The
* value defaults to "Not provided" but may be set to null, which will cause this element to be omitted.
* Gets the value of the "publisher" that will be placed in the generated conformance statement. As this is a
* mandatory element, the value should not be null (although this is not enforced). The value defaults to
* "Not provided" but may be set to null, which will cause this element to be omitted.
*/
public String getPublisher() {
return myPublisher;
@ -96,10 +107,10 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
Conformance retVal = new Conformance();
retVal.setPublisher(myPublisher);
retVal.setDateElement(DateTimeType.now());
retVal.setDate(new Date());
retVal.setFhirVersion("0.5.0"); // TODO: pull from model
retVal.setAcceptUnknown(false); // TODO: make this configurable - this is a fairly big effort since the parser
// needs to be modified to actually allow it
// needs to be modified to actually allow it
retVal.getImplementation().setDescription(myRestfulServer.getImplementationDescription());
retVal.getSoftware().setName(myRestfulServer.getServerName());
@ -112,103 +123,167 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
Set<SystemRestfulInteraction> systemOps = new HashSet<SystemRestfulInteraction>();
List<ResourceBinding> bindings = new ArrayList<ResourceBinding>(myRestfulServer.getResourceBindings());
Collections.sort(bindings, new Comparator<ResourceBinding>() {
@Override
public int compare(ResourceBinding theArg0, ResourceBinding theArg1) {
return theArg0.getResourceName().compareToIgnoreCase(theArg1.getResourceName());
}
});
for (ResourceBinding next : bindings) {
Set<TypeRestfulInteraction> resourceOps = new HashSet<TypeRestfulInteraction>();
ConformanceRestResourceComponent resource = rest.addResource();
Map<String, List<BaseMethodBinding<?>>> resourceToMethods = new TreeMap<String, List<BaseMethodBinding<?>>>();
for (ResourceBinding next : myRestfulServer.getResourceBindings()) {
String resourceName = next.getResourceName();
RuntimeResourceDefinition def = myRestfulServer.getFhirContext().getResourceDefinition(resourceName);
resource.getTypeElement().setValue(def.getName());
resource.getProfile().setReference(def.getResourceProfile(myRestfulServer.getServerBaseForRequest(theRequest)));
TreeSet<String> includes = new TreeSet<String>();
// Map<String, Conformance.RestResourceSearchParam> nameToSearchParam = new HashMap<String,
// Conformance.RestResourceSearchParam>();
for (BaseMethodBinding<?> nextMethodBinding : next.getMethodBindings()) {
if (nextMethodBinding.getResourceOperationType() != null) {
String resOpCode = nextMethodBinding.getResourceOperationType().getCode();
if (resOpCode != null) {
TypeRestfulInteraction resOp;
try {
resOp = TypeRestfulInteraction.fromCode(resOpCode);
} catch (Exception e) {
resOp = null;
}
if (resOp == null) {
throw new InternalErrorException("Unknown type-restful-interaction: " + resOpCode);
}
if (resourceOps.contains(resOp) == false) {
resourceOps.add(resOp);
resource.addInteraction().setCode(resOp);
}
}
if (resourceToMethods.containsKey(resourceName) == false) {
resourceToMethods.put(resourceName, new ArrayList<BaseMethodBinding<?>>());
}
if (nextMethodBinding.getSystemOperationType() != null) {
String sysOpCode = nextMethodBinding.getSystemOperationType().getCode();
if (sysOpCode != null) {
SystemRestfulInteraction sysOp;
try {
sysOp = SystemRestfulInteraction.fromCode(sysOpCode);
} catch (Exception e) {
sysOp = null;
}
if (sysOp == null) {
throw new InternalErrorException("Unknown system-restful-interaction: " + sysOpCode);
}
if (systemOps.contains(sysOp) == false) {
systemOps.add(sysOp);
rest.addInteraction().setCode(sysOp);
}
}
}
if (nextMethodBinding instanceof SearchMethodBinding) {
handleSearchMethodBinding(rest, resource, resourceName, def, includes, (SearchMethodBinding) nextMethodBinding);
} else if (nextMethodBinding instanceof DynamicSearchMethodBinding) {
handleDynamicSearchMethodBinding(resource, def, includes, (DynamicSearchMethodBinding) nextMethodBinding);
}
Collections.sort(resource.getInteraction(), new Comparator<ResourceInteractionComponent>() {
@Override
public int compare(ResourceInteractionComponent theO1, ResourceInteractionComponent theO2) {
TypeRestfulInteraction o1 = theO1.getCodeElement().getValue();
TypeRestfulInteraction o2 = theO2.getCodeElement().getValue();
if (o1 == null && o2 == null) {
return 0;
}
if (o1 == null) {
return 1;
}
if (o2 == null) {
return -1;
}
return o1.ordinal() - o2.ordinal();
}
});
resourceToMethods.get(resourceName).add(nextMethodBinding);
}
for (String nextInclude : includes) {
resource.addSearchInclude(nextInclude);
}
for (BaseMethodBinding<?> nextMethodBinding : myRestfulServer.getServerBindings()) {
String resourceName = "";
if (resourceToMethods.containsKey(resourceName) == false) {
resourceToMethods.put(resourceName, new ArrayList<BaseMethodBinding<?>>());
}
resourceToMethods.get(resourceName).add(nextMethodBinding);
}
for (Entry<String, List<BaseMethodBinding<?>>> nextEntry : resourceToMethods.entrySet()) {
if (nextEntry.getKey().isEmpty() == false) {
Set<TypeRestfulInteraction> resourceOps = new HashSet<TypeRestfulInteraction>();
ConformanceRestResourceComponent resource = rest.addResource();
String resourceName = nextEntry.getKey();
RuntimeResourceDefinition def = myRestfulServer.getFhirContext().getResourceDefinition(resourceName);
resource.getTypeElement().setValue(def.getName());
resource.getProfile().setReference(def.getResourceProfile(myRestfulServer.getServerBaseForRequest(theRequest)));
TreeSet<String> includes = new TreeSet<String>();
// Map<String, Conformance.RestResourceSearchParam> nameToSearchParam = new HashMap<String,
// Conformance.RestResourceSearchParam>();
for (BaseMethodBinding<?> nextMethodBinding : nextEntry.getValue()) {
if (nextMethodBinding.getResourceOperationType() != null) {
String resOpCode = nextMethodBinding.getResourceOperationType().getCode();
if (resOpCode != null) {
TypeRestfulInteraction resOp;
try {
resOp = TypeRestfulInteraction.fromCode(resOpCode);
assert resOp != null;
} catch (Exception e) {
throw new InternalErrorException("Unknown type-restful-interaction: " + resOpCode);
}
if (resourceOps.contains(resOp) == false) {
resourceOps.add(resOp);
resource.addInteraction().setCode(resOp);
}
if ("vread".equals(resOpCode)) {
// vread implies read
resOp = TypeRestfulInteraction.READ;
if (resourceOps.contains(resOp) == false) {
resourceOps.add(resOp);
resource.addInteraction().setCode(resOp);
}
}
if (nextMethodBinding.isSupportsConditional()) {
switch (resOp) {
case CREATE:
resource.setConditionalCreate(true);
break;
case DELETE:
resource.setConditionalDelete(true);
break;
case UPDATE:
resource.setConditionalUpdate(true);
break;
default:
break;
}
}
}
}
checkBindingForSystemOps(rest, systemOps, nextMethodBinding);
if (nextMethodBinding instanceof SearchMethodBinding) {
handleSearchMethodBinding(rest, resource, resourceName, def, includes, (SearchMethodBinding) nextMethodBinding);
} else if (nextMethodBinding instanceof DynamicSearchMethodBinding) {
handleDynamicSearchMethodBinding(resource, def, includes, (DynamicSearchMethodBinding) nextMethodBinding);
} else if (nextMethodBinding instanceof OperationMethodBinding) {
OperationMethodBinding methodBinding = (OperationMethodBinding) nextMethodBinding;
OperationDefinition op = new OperationDefinition();
rest.addOperation().setName(methodBinding.getName()).getDefinition().setResource(op);
;
op.setStatus(ConformanceResourceStatus.ACTIVE);
op.setDescription(methodBinding.getDescription());
op.setIdempotent(methodBinding.isIdempotent());
op.setCode(methodBinding.getName());
op.setInstance(methodBinding.isInstanceLevel());
op.addType(methodBinding.getResourceName());
for (IParameter nextParamUntyped : methodBinding.getParameters()) {
if (nextParamUntyped instanceof OperationParameter) {
OperationParameter nextParam = (OperationParameter) nextParamUntyped;
OperationDefinitionParameterComponent param = op.addParameter();
param.setUse(OperationParameterUse.IN);
if (nextParam.getParamType() != null) {
param.setType(nextParam.getParamType().getCode());
}
param.setMin(nextParam.getMin());
param.setMax(nextParam.getMax() == -1 ? "*" : Integer.toString(nextParam.getMax()));
param.setName(nextParam.getName());
}
}
}
Collections.sort(resource.getInteraction(), new Comparator<ResourceInteractionComponent>() {
@Override
public int compare(ResourceInteractionComponent theO1, ResourceInteractionComponent theO2) {
TypeRestfulInteraction o1 = theO1.getCode();
TypeRestfulInteraction o2 = theO2.getCode();
if (o1 == null && o2 == null) {
return 0;
}
if (o1 == null) {
return 1;
}
if (o2 == null) {
return -1;
}
return o1.ordinal() - o2.ordinal();
}
});
}
for (String nextInclude : includes) {
resource.addSearchInclude(nextInclude);
}
} else {
for (BaseMethodBinding<?> nextMethodBinding : nextEntry.getValue()) {
checkBindingForSystemOps(rest, systemOps, nextMethodBinding);
}
}
}
myConformance = retVal;
return retVal;
}
private void checkBindingForSystemOps(ConformanceRestComponent rest, Set<SystemRestfulInteraction> systemOps, BaseMethodBinding<?> nextMethodBinding) {
if (nextMethodBinding.getSystemOperationType() != null) {
String sysOpCode = nextMethodBinding.getSystemOperationType().getCode();
if (sysOpCode != null) {
SystemRestfulInteraction sysOp;
try {
sysOp = SystemRestfulInteraction.fromCode(sysOpCode);
assert sysOp != null;
} catch (Exception e) {
throw new InternalErrorException("Unknown system-restful-interaction: " + sysOpCode);
}
if (systemOps.contains(sysOp) == false) {
systemOps.add(sysOp);
rest.addInteraction().setCode(sysOp);
}
}
}
}
private void handleDynamicSearchMethodBinding(ConformanceRestResourceComponent resource, RuntimeResourceDefinition def, TreeSet<String> includes, DynamicSearchMethodBinding searchMethodBinding) {
includes.addAll(searchMethodBinding.getIncludes());
@ -303,7 +378,7 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
}
}
ConformanceRestResourceSearchParamComponent param = resource.addSearchParam();
ConformanceRestResourceSearchParamComponent param = resource.addSearchParam();
param.setName(nextParamUnchainedName);
if (StringUtils.isNotBlank(chain)) {
param.addChain(chain);
@ -315,9 +390,8 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
for (Class<? extends IResource> nextTarget : nextParameter.getDeclaredTypes()) {
RuntimeResourceDefinition targetDef = myRestfulServer.getFhirContext().getResourceDefinition(nextTarget);
if (targetDef != null) {
ResourceType code = ResourceType.valueOf(targetDef.getName());
if (code != null) {
param.addTarget(code.name());
if (isNotBlank(targetDef.getName())) {
param.addTarget(targetDef.getName());
}
}
}
@ -336,8 +410,9 @@ public class ServerConformanceProvider implements IServerConformanceProvider<Con
}
/**
* Sets the value of the "publisher" that will be placed in the generated conformance statement. As this is a mandatory element, the value should not be null (although this is not enforced). The
* value defaults to "Not provided" but may be set to null, which will cause this element to be omitted.
* Sets the value of the "publisher" that will be placed in the generated conformance statement. As this is a
* mandatory element, the value should not be null (although this is not enforced). The value defaults to
* "Not provided" but may be set to null, which will cause this element to be omitted.
*/
public void setPublisher(String thePublisher) {
myPublisher = thePublisher;

View File

@ -45,7 +45,7 @@ import org.hl7.fhir.instance.model.api.*;
* A conformance statement is a set of requirements for a desired implementation or a description of how a target application fulfills those requirements in a particular implementation.
*/
@ResourceDef(name="Conformance", profile="http://hl7.org/fhir/Profile/Conformance")
public class Conformance extends DomainResource {
public class Conformance extends DomainResource implements IBaseConformance {
public enum RestfulConformanceMode {
/**

View File

@ -31,20 +31,21 @@ package org.hl7.fhir.instance.model;
// Generated on Sun, May 31, 2015 15:45-0400 for FHIR v0.5.0
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import org.hl7.fhir.utilities.Utilities;
import org.hl7.fhir.instance.model.annotations.ResourceDef;
import org.hl7.fhir.instance.model.annotations.SearchParamDefinition;
import org.hl7.fhir.instance.model.annotations.Block;
import org.hl7.fhir.instance.model.annotations.Child;
import org.hl7.fhir.instance.model.annotations.Description;
import org.hl7.fhir.instance.model.annotations.Block;
import org.hl7.fhir.instance.model.api.*;
import org.hl7.fhir.instance.model.annotations.ResourceDef;
import org.hl7.fhir.instance.model.api.IBaseBackboneElement;
import org.hl7.fhir.instance.model.api.IBaseOperationOutcome;
import org.hl7.fhir.utilities.Utilities;
/**
* A collection of error, warning or information messages that result from a system action.
*/
@ResourceDef(name="OperationOutcome", profile="http://hl7.org/fhir/Profile/OperationOutcome")
public class OperationOutcome extends DomainResource {
public class OperationOutcome extends DomainResource implements IBaseOperationOutcome {
public enum IssueSeverity {
/**

View File

@ -704,7 +704,7 @@ public class Utilities {
StringBuilder b = new StringBuilder();
boolean lastBreak = true;
for (char c : code.toCharArray()) {
if (Character.isAlphabetic(c)) {
if (isAlphabetic(c)) {
if (lastBreak)
b.append(Character.toUpperCase(c));
else {

View File

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource AllergyIntolerance
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>AllergyIntolerance</sch:title>
<sch:rule context="f:AllergyIntolerance/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:recorder">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:patient">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:reporter">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:substance">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:substance/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:event/f:substance">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:event/f:substance/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:event/f:manifestation">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:event/f:manifestation/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:event/f:duration">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:event/f:exposureRoute">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:AllergyIntolerance/f:event/f:exposureRoute/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource Appointment
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>Appointment</sch:title>
<sch:rule context="f:Appointment/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Appointment/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Appointment">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:Appointment/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:Appointment/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Appointment/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Appointment/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Appointment/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Appointment/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Appointment/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Appointment/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Appointment/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Appointment/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Appointment/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Appointment/f:reason">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Appointment/f:reason/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Appointment/f:slot">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Appointment/f:order">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Appointment/f:participant/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Appointment/f:participant/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Appointment/f:participant/f:actor">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource AppointmentResponse
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>AppointmentResponse</sch:title>
<sch:rule context="f:AppointmentResponse/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AppointmentResponse/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AppointmentResponse">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:AppointmentResponse/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:AppointmentResponse/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AppointmentResponse/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AppointmentResponse/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AppointmentResponse/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AppointmentResponse/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:AppointmentResponse/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AppointmentResponse/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:AppointmentResponse/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:AppointmentResponse/f:appointment">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:AppointmentResponse/f:participantType">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:AppointmentResponse/f:participantType/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AppointmentResponse/f:actor">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,115 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource AuditEvent
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>AuditEvent</sch:title>
<sch:rule context="f:AuditEvent/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:event/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:event/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:event/f:subtype">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:event/f:subtype/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:event/f:purposeOfEvent">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:participant">
<sch:assert test="exists(f:userId) != exists(f:reference)">sev-3: Either a userId or a reference, but not both</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:participant/f:role">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:participant/f:role/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:participant/f:reference">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:participant/f:location">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:participant/f:media">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:participant/f:purposeOfUse">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:source/f:type">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:object">
<sch:assert test="not(exists(f:name)) or not(exists(f:query))">sev-1: Either a name or a query (or both)</sch:assert>
<sch:assert test="exists(f:identifier) != exists(f:reference)">sev-2: Either an identifier or a reference, but not both</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:object/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:object/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:object/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:object/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:object/f:reference">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:object/f:sensitivity">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:AuditEvent/f:object/f:sensitivity/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource Basic
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>Basic</sch:title>
<sch:rule context="f:Basic/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Basic/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Basic">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:Basic/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:Basic/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Basic/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Basic/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Basic/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Basic/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Basic/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Basic/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Basic/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Basic/f:code">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Basic/f:code/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Basic/f:subject">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Basic/f:author">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource Binary
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>Binary</sch:title>
<sch:rule context="f:Binary/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Binary/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource BodySite
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>BodySite</sch:title>
<sch:rule context="f:BodySite/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:BodySite/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:BodySite">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:BodySite/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:BodySite/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:BodySite/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:BodySite/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:BodySite/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:BodySite/f:patient">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:BodySite/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:BodySite/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:BodySite/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:BodySite/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:BodySite/f:code">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:BodySite/f:code/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:BodySite/f:modifier">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:BodySite/f:modifier/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:BodySite/f:image">
<sch:assert test="not(exists(f:data)) or exists(f:contentType)">att-1: It the Attachment has data, it SHALL have a contentType</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource Bundle
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>Bundle</sch:title>
<sch:rule context="f:Bundle/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Bundle/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Bundle">
<sch:assert test="not(f:entry/f:transaction) or (f:type/@value = 'transaction') or (f:type/@value = 'history')">bdl-3: entry.transaction when (and only when) a transaction</sch:assert>
<sch:assert test="not(f:entry/f:transactionResponse) or (f:type/@value = 'transaction-response')">bdl-4: entry.transactionResponse when (and only when) a transaction-response</sch:assert>
<sch:assert test="not(f:total) or (f:type/@value = 'searchset') or (f:type/@value = 'history')">bdl-1: total only when a search or history</sch:assert>
<sch:assert test="not(f:entry/f:search) or (f:type/@value = 'searchset')">bdl-2: entry.search only when a search</sch:assert>
</sch:rule>
<sch:rule context="f:Bundle/f:entry">
<sch:assert test="f:resource or f:transaction or f:transactionResponse">bdl-5: must be a resource unless there's a transaction or transaction response</sch:assert>
</sch:rule>
<sch:rule context="f:Bundle/f:entry/f:resource/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Bundle/f:entry/f:resource/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Bundle/f:entry/f:resource/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Bundle/f:entry/f:resource/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,171 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource CarePlan
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>CarePlan</sch:title>
<sch:rule context="f:CarePlan/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:patient">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:author">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:category">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:category/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:concern">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:support">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:participant/f:role">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:participant/f:role/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:participant/f:member">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:goal">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:actionResulting">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:reference">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:detail">
<sch:assert test="not(exists(f:detail)) or not(exists(f:simple))">cpl-3: Only provide a detail reference, or a simple detail summary</sch:assert>
<sch:assert test="(f:category/@value=('supply')) = exists(f:quantity)">cpl-2: Quantity can only be specified if activity category is supply</sch:assert>
<sch:assert test="(f:category/@value=('drug','diet')) = exists(f:dailyAmount)">cpl-1: DailyDose can only be specified if activity category is drug or food</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:detail/f:code">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:detail/f:code/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:detail/f:reasonCodeableConcept">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:detail/f:reasonCodeableConcept/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:detail/f:reasonReference">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:detail/f:goal">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:detail/f:statusReason">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:detail/f:statusReason/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:repeat">
<sch:assert test="not(exists(f:periodMax)) or exists(period)">tim-6: If there's a periodMax, there must be a period</sch:assert>
<sch:assert test="not(exists(f:durationMax)) or exists(duration)">tim-7: If there's a durationMax, there must be a duration</sch:assert>
<sch:assert test="not(exists(f:duration)) or exists(f:durationUnits)">tim-1: if there's a duration, there needs to be duration units</sch:assert>
<sch:assert test="not(exists(f:period)) or exists(f:periodUnits)">tim-2: if there's a period, there needs to be duration units</sch:assert>
<sch:assert test="not(exists(f:frequency)) or not(exists(f:when))">tim-3: Either frequency or when can exist, not both</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:repeat/f:bounds">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:repeat/f:duration">
<sch:assert test="@value &gt;= 0 or not(@value)">tim-4: duration SHALL be a non-negative value</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:repeat/f:period">
<sch:assert test="@value &gt;= 0 or not(@value)">tim-5: period SHALL be a non-negative value</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:code">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:detail/f:scheduledTiming/f:code/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:detail/f:scheduledPeriod">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:detail/f:location">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:detail/f:performer">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:detail/f:product">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:detail/f:dailyAmount">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:CarePlan/f:activity/f:detail/f:quantity">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,219 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource Claim
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>Claim</sch:title>
<sch:rule context="f:Claim/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:ruleset">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:originalRuleset">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:target">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:provider">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:organization">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:priority">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:fundsReserve">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:enterer">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:facility">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:prescription">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:originalPrescription">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:payee/f:type">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:payee/f:provider">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:payee/f:organization">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:payee/f:person">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:referral">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:diagnosis/f:diagnosis">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:condition">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:patient">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:coverage/f:coverage">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:coverage/f:relationship">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:coverage/f:claimResponse">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:coverage/f:originalRuleset">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:exception">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:accidentType">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:interventionException">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:type">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:provider">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:service">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:quantity">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:unitPrice">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:net">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:udi">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:bodySite">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:subSite">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:modifier">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:detail/f:type">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:detail/f:service">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:detail/f:quantity">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:detail/f:unitPrice">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:detail/f:net">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:detail/f:udi">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:detail/f:subDetail/f:type">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:detail/f:subDetail/f:service">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:detail/f:subDetail/f:quantity">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:detail/f:subDetail/f:unitPrice">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:detail/f:subDetail/f:net">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:detail/f:subDetail/f:udi">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:item/f:prosthesis/f:priorMaterial">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:additionalMaterials">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:missingTeeth/f:tooth">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Claim/f:missingTeeth/f:reason">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,180 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource ClaimResponse
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>ClaimResponse</sch:title>
<sch:rule context="f:ClaimResponse/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:request">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:ruleset">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:originalRuleset">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:organization">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:requestProvider">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:requestOrganization">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:payeeType">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:item/f:adjudication/f:code">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:item/f:adjudication/f:amount">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:item/f:detail/f:adjudication/f:code">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:item/f:detail/f:adjudication/f:amount">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:item/f:detail/f:subDetail/f:adjudication/f:code">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:item/f:detail/f:subDetail/f:adjudication/f:amount">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:addItem/f:service">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:addItem/f:fee">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:addItem/f:adjudication/f:code">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:addItem/f:adjudication/f:amount">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:addItem/f:detail/f:service">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:addItem/f:detail/f:fee">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:addItem/f:detail/f:adjudication/f:code">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:addItem/f:detail/f:adjudication/f:amount">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:error/f:code">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:totalCost">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:unallocDeductable">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:totalBenefit">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:paymentAdjustment">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:paymentAdjustmentReason">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:paymentAmount">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:paymentRef/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:paymentRef/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:paymentRef/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:paymentRef/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:reserved">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:form">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:note/f:type">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:coverage/f:coverage">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:coverage/f:relationship">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:coverage/f:claimResponse">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:ClaimResponse/f:coverage/f:originalRuleset">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,105 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource ClinicalImpression
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>ClinicalImpression</sch:title>
<sch:rule context="f:ClinicalImpression/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:patient">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:assessor">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:previous">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:problem">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:triggerCodeableConcept">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:triggerCodeableConcept/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:triggerReference">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:investigations/f:code">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:investigations/f:code/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:investigations/f:item">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:finding/f:item">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:finding/f:item/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:resolved">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:resolved/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:ruledOut/f:item">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:ruledOut/f:item/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:plan">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:ClinicalImpression/f:action">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource Communication
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>Communication</sch:title>
<sch:rule context="f:Communication/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Communication">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:category">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:category/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:sender">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:recipient">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:payload/f:contentAttachment">
<sch:assert test="not(exists(f:data)) or exists(f:contentType)">att-1: It the Attachment has data, it SHALL have a contentType</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:payload/f:contentReference">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:medium">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:medium/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:encounter">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:reason">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:reason/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Communication/f:subject">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource CommunicationRequest
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>CommunicationRequest</sch:title>
<sch:rule context="f:CommunicationRequest/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:category">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:category/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:sender">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:recipient">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:payload/f:contentAttachment">
<sch:assert test="not(exists(f:data)) or exists(f:contentType)">att-1: It the Attachment has data, it SHALL have a contentType</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:payload/f:contentReference">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:medium">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:medium/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:requester">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:encounter">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:reason">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:reason/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:subject">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:priority">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:CommunicationRequest/f:priority/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource Composition
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>Composition</sch:title>
<sch:rule context="f:Composition/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Composition">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:class">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:class/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:subject">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:author">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:attester/f:party">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:custodian">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:event/f:code">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:event/f:code/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:event/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:event/f:detail">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:encounter">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:section">
<sch:assert test="(exists(f:content) and not(exists(f:section))) or (exists(f:section) and not(exists(f:content)))">cmp-1: A section must have either subsections or content</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:section/f:code">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:section/f:code/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Composition/f:section/f:content">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource ConceptMap
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>ConceptMap</sch:title>
<sch:rule context="f:ConceptMap/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ConceptMap/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ConceptMap">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:ConceptMap/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:ConceptMap/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ConceptMap/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ConceptMap/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ConceptMap/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ConceptMap/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:ConceptMap/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ConceptMap/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:ConceptMap/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:ConceptMap/f:useContext">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:ConceptMap/f:useContext/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:ConceptMap/f:contact/f:telecom">
<sch:assert test="not(exists(f:value)) or exists(f:system)">cpt-2: A system is required if a value is provided.</sch:assert>
</sch:rule>
<sch:rule context="f:ConceptMap/f:contact/f:telecom/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:ConceptMap/f:sourceReference">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:ConceptMap/f:targetReference">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:ConceptMap/f:element/f:map">
<sch:assert test="exists(f:comments) or ((f:equivalence/@value != 'narrower') and (f:equivalence/@value != 'inexact'))">cmd-1: If the map is narrower or inexact, there SHALL be some comments</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,179 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource Condition
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>Condition</sch:title>
<sch:rule context="f:Condition/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Condition">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:patient">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:encounter">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:asserter">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:code">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:code/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:category">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:category/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:severity">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:severity/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:onsetAge">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:onsetPeriod">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:onsetRange">
<sch:assert test="not(exists(f:low/f:value/@value)) or not(exists(f:high/f:value/@value)) or (number(f:low/f:value/@value) &lt;= number(f:high/f:value/@value))">rng-2: If present, low SHALL have a lower value than high</sch:assert>
<sch:assert test="not(exists(f:low/f:comparator) or exists(f:high/f:comparator))">rng-3: Quantity values cannot have a comparator when used in a Range</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:onsetRange/f:low">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:onsetRange/f:high">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:abatementAge">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:abatementPeriod">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:abatementRange">
<sch:assert test="not(exists(f:low/f:value/@value)) or not(exists(f:high/f:value/@value)) or (number(f:low/f:value/@value) &lt;= number(f:high/f:value/@value))">rng-2: If present, low SHALL have a lower value than high</sch:assert>
<sch:assert test="not(exists(f:low/f:comparator) or exists(f:high/f:comparator))">rng-3: Quantity values cannot have a comparator when used in a Range</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:abatementRange/f:low">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:abatementRange/f:high">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:stage">
<sch:assert test="exists(f:summary) or exists(f:assessment)">con-1: Stage SHALL have summary or assessment</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:stage/f:summary">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:stage/f:summary/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:stage/f:assessment">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:evidence">
<sch:assert test="exists(f:code) or exists(f:detail)">con-2: evidence SHALL have code or details</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:evidence/f:code">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:evidence/f:code/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:evidence/f:detail">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:location/f:siteCodeableConcept">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:location/f:siteCodeableConcept/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:location/f:siteReference">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:dueTo">
<sch:assert test="exists(f:code) != exists(f:target)">con-4: Relationship SHALL have either a code or a target</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:dueTo/f:code">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:dueTo/f:code/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:dueTo/f:target">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:occurredFollowing">
<sch:assert test="exists(f:code) != exists(f:target)">con-5: Relationship SHALL have either a code or a target</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:occurredFollowing/f:code">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:occurredFollowing/f:code/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Condition/f:occurredFollowing/f:target">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource Conformance
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>Conformance</sch:title>
<sch:rule context="f:Conformance/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance">
<sch:assert test="count(f:rest)=count(distinct-values(f:rest/f:mode/@value))">cnf-8: There can only be one REST declaration per mode</sch:assert>
<sch:assert test="count(f:document[f:mode='producer'])=count(distinct-values(f:document[f:mode='producer']/f:profile/@value)) and count(f:document[f:mode='consumer'])=count(distinct-values(f:document[f:mode='consumer']/f:profile/@value))">cnf-7: The set of documents must be unique by the combination of profile &amp; mode</sch:assert>
<sch:assert test="count(f:messaging)&lt;=1 or not(f:messaging[not(f:endpoint)])">cnf-4: If there is more than one messaging element, endpoint must be specified for each one</sch:assert>
<sch:assert test="count(f:messaging/f:endpoint)=count(distinct-values(f:messaging/f:endpoint/@value))">cnf-5: The set of end points listed for messaging must be unique</sch:assert>
<sch:assert test="count(f:software | f:implementation | f:description) &gt; 0">cnf-2: A Conformance statement SHALL have at least one of description, software, or implementation</sch:assert>
<sch:assert test="exists(f:rest) or exists(f:messaging) or exists(f:document)">cnf-1: A Conformance statement SHALL have at least one of rest, messaging or document</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance/f:contact/f:telecom">
<sch:assert test="not(exists(f:value)) or exists(f:system)">cpt-2: A system is required if a value is provided.</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance/f:contact/f:telecom/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance/f:profile">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance/f:rest">
<sch:assert test="count(f:resource)=count(distinct-values(f:resource/f:type/@value))">cnf-9: A given resource can only be described once per RESTful mode</sch:assert>
<sch:assert test="count(f:query)=count(distinct-values(f:query/f:name/@value))">cnf-10: A given query can only be described once per RESTful mode</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance/f:rest/f:security/f:service">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance/f:rest/f:security/f:service/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance/f:rest/f:resource">
<sch:assert test="count(f:operation)=count(distinct-values(f:operation/f:code/@value))">cnf-11: Operation codes must be unique in the context of a resource</sch:assert>
<sch:assert test="count(f:searchParam)=count(distinct-values(f:searchParam/f:name/@value))">cnf-12: Search parameter names must be unique in the context of a resource</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance/f:rest/f:resource/f:profile">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance/f:rest/f:operation/f:definition">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance/f:messaging">
<sch:assert test="count(f:event[f:mode='sender'])=count(distinct-values(f:event[f:mode='sender']/f:code/@value)) and count(f:event[f:mode='receiver'])=count(distinct-values(f:event[f:mode='receiver']/f:code/@value))">cnf-6: The set of events per messaging endpoint must be unique by the combination of code &amp; mode</sch:assert>
<sch:assert test="exists(f:endpoint) = exists(parent::f:Conformance/f:implementation)">cnf-3: Messaging end point is required (and is only permitted) when statement is for an implementation</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance/f:messaging/f:event/f:code">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance/f:messaging/f:event/f:protocol">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance/f:messaging/f:event/f:request">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance/f:messaging/f:event/f:response">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Conformance/f:document/f:profile">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,249 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource Contract
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>Contract</sch:title>
<sch:rule context="f:Contract/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:applies">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:subject">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:authority">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:domain">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:subType">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:subType/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:action">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:action/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:actionReason">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:actionReason/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:actor/f:entity">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:actor/f:role">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:actor/f:role/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:valuedItem/f:entityCodeableConcept">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:valuedItem/f:entityCodeableConcept/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:valuedItem/f:entityReference">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:valuedItem/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:valuedItem/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:valuedItem/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:valuedItem/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:valuedItem/f:quantity">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:valuedItem/f:unitPrice">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:valuedItem/f:net">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:signer/f:type">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:signer/f:party">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:applies">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:subType">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:subType/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:subject">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:action">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:action/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:actionReason">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:actionReason/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:actor/f:entity">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:actor/f:role">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:actor/f:role/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:valuedItem/f:entityCodeableConcept">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:valuedItem/f:entityCodeableConcept/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:valuedItem/f:entityReference">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:valuedItem/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:valuedItem/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:valuedItem/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:valuedItem/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:valuedItem/f:quantity">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:valuedItem/f:unitPrice">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:term/f:valuedItem/f:net">
<sch:assert test="not(exists(f:code)) or exists(f:system)">qty-3: If a code for the units is present, the system SHALL also be present</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:bindingAttachment">
<sch:assert test="not(exists(f:data)) or exists(f:contentType)">att-1: It the Attachment has data, it SHALL have a contentType</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:bindingReference">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:friendly/f:contentAttachment">
<sch:assert test="not(exists(f:data)) or exists(f:contentType)">att-1: It the Attachment has data, it SHALL have a contentType</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:friendly/f:contentReference">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:legal/f:contentAttachment">
<sch:assert test="not(exists(f:data)) or exists(f:contentType)">att-1: It the Attachment has data, it SHALL have a contentType</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:legal/f:contentReference">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:rule/f:contentAttachment">
<sch:assert test="not(exists(f:data)) or exists(f:contentType)">att-1: It the Attachment has data, it SHALL have a contentType</sch:assert>
</sch:rule>
<sch:rule context="f:Contract/f:rule/f:contentReference">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource Contraindication
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>Contraindication</sch:title>
<sch:rule context="f:Contraindication/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contraindication/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contraindication">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:Contraindication/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:Contraindication/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contraindication/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contraindication/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contraindication/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contraindication/f:patient">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Contraindication/f:category">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Contraindication/f:category/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contraindication/f:implicated">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Contraindication/f:author">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Contraindication/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Contraindication/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contraindication/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Contraindication/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Contraindication/f:mitigation/f:action">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Contraindication/f:mitigation/f:action/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Contraindication/f:mitigation/f:author">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource Coverage
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>Coverage</sch:title>
<sch:rule context="f:Coverage/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:issuer">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:bin/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:bin/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:bin/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:bin/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:type">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:subscriberId/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:subscriberId/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:subscriberId/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:subscriberId/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:subscriber">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:network/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:network/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:network/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:network/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Coverage/f:contract">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,109 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource DataElement
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>DataElement</sch:title>
<sch:rule context="f:DataElement/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:useContext">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:useContext/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:contact/f:telecom">
<sch:assert test="not(exists(f:value)) or exists(f:system)">cpt-2: A system is required if a value is provided.</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:contact/f:telecom/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:element">
<sch:assert test="(not(f:max/@value) and not(f:min/@value)) or (f:max/@value = '*') or (f:max/@value &gt;= f:min/@value)">eld-2: Min &lt;= Max</sch:assert>
<sch:assert test="not(exists(f:nameReference) and exists(f:*[starts-with(local-name(.), 'value')]))">eld-5: Either a namereference or a fixed value (but not both) is permitted</sch:assert>
<sch:assert test="not(exists(f:*[starts-with(local-name(.), 'pattern')])) or (count(f:type)=1 )">eld-7: Pattern may only be specified if there is one type</sch:assert>
<sch:assert test="not(exists(f:*[starts-with(local-name(.), 'fixed')])) or (count(f:type)=1 )">eld-6: Fixed value may only be specified if there is one type</sch:assert>
<sch:assert test="not(exists(f:binding)) or (count(f:type/f:code) = 0) or f:type/f:code/@value=('code','Coding','CodeableConcept','Quantity','Extension', 'string', 'uri')">eld-11: Binding can only be present for coded elements, string, and uri</sch:assert>
<sch:assert test="not(exists(f:*[starts-with(local-name(.), 'pattern')])) or not(exists(f:*[starts-with(local-name(.), 'value')]))">eld-8: Pattern and value are mutually exclusive</sch:assert>
<sch:assert test="count(f:constraint) = count(distinct-values(f:constraint/f:key/@value))">eld-14: Constraints must be unique by key</sch:assert>
<sch:assert test="not(exists(for $type in f:type return $type/preceding-sibling::f:type[f:code/@value=$type/f:code/@value and f:profile/@value = $type/f:profile/@value]))">eld-13: Types must be unique by the combination of code and profile</sch:assert>
<sch:assert test="not(exists(f:*[starts-with(local-name(.), 'fixed')])) or not(exists(f:meaningWhenMissing))">eld-16: default value and meaningWhenMissing are mutually exclusive</sch:assert>
<sch:assert test="count(f:constraint[f:name]) = count(distinct-values(f:constraint/f:name/@value))">eld-15: Constraint names must be unique.</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:element/f:code">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:element/f:slicing">
<sch:assert test="(f:discriminator) or (f:definition)">eld-1: If there are no discriminators, there must be a definition</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:element/f:max">
<sch:assert test="@value='*' or (normalize-space(@value)!='' and normalize-space(translate(@value, '0123456789',''))='')">eld-3: Max SHALL be a number or &quot;*&quot;</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:element/f:type">
<sch:assert test="not(exists(f:aggregation)) or exists(f:code[@value = 'Reference'])">eld-4: Aggregation may only be specified if one of the allowed types for the element is a resource</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:element/f:binding">
<sch:assert test="(exists(f:valueSetUri) or exists(f:valueSetReference)) or exists(f:description)">eld-10: provide either a reference or a description (or both)</sch:assert>
<sch:assert test="not(f:conformance/@value='example' and f:isExtensible/@value='false')">eld-9: Example value sets are always extensible</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:element/f:binding/f:valueSetUri">
<sch:assert test="starts-with(@value, 'http:') or starts-with(@value, 'https:')">eld-12: uri SHALL start with http:// or https://</sch:assert>
</sch:rule>
<sch:rule context="f:DataElement/f:element/f:binding/f:valueSetReference">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource Device
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>Device</sch:title>
<sch:rule context="f:Device/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Device/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Device">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:Device/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:Device/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Device/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Device/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Device/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Device/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Device/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Device/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:Device/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Device/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:Device/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:Device/f:owner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Device/f:location">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Device/f:patient">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:Device/f:contact">
<sch:assert test="not(exists(f:value)) or exists(f:system)">cpt-2: A system is required if a value is provided.</sch:assert>
</sch:rule>
<sch:rule context="f:Device/f:contact/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource DeviceComponent
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>DeviceComponent</sch:title>
<sch:rule context="f:DeviceComponent/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:source">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:parent">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:operationalStatus">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:operationalStatus/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:parameterGroup">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:parameterGroup/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:productionSpecification/f:specType">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:productionSpecification/f:specType/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:productionSpecification/f:componentId/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:productionSpecification/f:componentId/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:productionSpecification/f:componentId/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:productionSpecification/f:componentId/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:languageCode">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceComponent/f:languageCode/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

View File

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="UTF-8"?>
<sch:schema xmlns:sch="http://purl.oclc.org/dsdl/schematron" queryBinding="xslt2">
<sch:ns prefix="f" uri="http://hl7.org/fhir"/>
<sch:ns prefix="h" uri="http://www.w3.org/1999/xhtml"/>
<!--
This file contains just the constraints for the resource DeviceMetric
It is provided for documentation purposes. When actually validating,
always use fhir-invariants.sch (because of the way containment works)
Alternatively you can use this file to build a smaller version of
fhir-invariants.sch (the contents are identical; only include those
resources relevant to your implementation).
-->
<sch:pattern>
<sch:title>Global</sch:title>
<sch:rule context="f:*">
<sch:assert test="@value|f:*|h:div">global-1: All FHIR elements must have a @value or children</sch:assert>
</sch:rule>
</sch:pattern>
<sch:pattern>
<sch:title>DeviceMetric</sch:title>
<sch:rule context="f:DeviceMetric/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric">
<sch:assert test="not(parent::f:contained and f:contained)">dom-2: If the resource is contained in another resource, it SHALL not contain nested Resources</sch:assert>
<sch:assert test="not(parent::f:contained and f:text)">dom-1: If the resource is contained in another resource, it SHALL not contain any narrative</sch:assert>
<sch:assert test="not(exists(f:contained/f:meta/f:versionId)) and not(exists(f:contained/f:meta/f:lastUpdated))">dom-4: If a resource is contained in another resource, it SHALL not have a meta.versionId or a meta.lastUpdated</sch:assert>
<sch:assert test="not(exists(for $id in f:contained/*/@id return $id[not(ancestor::f:contained/parent::*/descendant::f:reference/@value=concat('#', $id))]))">dom-3: If the resource is contained in another resource, it SHALL be referred to from elsewhere in the resource</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:text/f:div">
<sch:assert test="not(descendant-or-self::*/@*[not(name(.)=('abbr', 'accesskey', 'align', 'alt', 'axis', 'bgcolor', 'border', 'cellhalign', 'cellpadding', 'cellspacing', 'cellvalign', 'char', 'charoff', 'charset', 'cite', 'class', 'colspan', 'compact', 'coords', 'dir', 'frame', 'headers', 'height', 'href', 'hreflang', 'hspace', 'id', 'lang', 'longdesc', 'name', 'nowrap', 'rel', 'rev', 'rowspan', 'rules', 'scope', 'shape', 'span', 'src', 'start', 'style', 'summary', 'tabindex', 'title', 'type', 'valign', 'value', 'vspace', 'width'))])">txt-3: The narrative SHALL contain only the basic html formatting attributes described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="not(descendant-or-self::*[not(local-name(.)=('a', 'abbr', 'acronym', 'b', 'big', 'blockquote', 'br', 'caption', 'cite', 'code', 'colgroup', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'i', 'img', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'small', 'span', 'strong', 'table', 'tbody', 'td', 'tfoot', 'th', 'thead', 'tr', 'tt', 'ul', 'var'))])">txt-1: The narrative SHALL contain only the basic html formatting elements described in chapters 7-11 (except section 4 of chapter 9) and 15 of the HTML 4.0 standard, &lt;a&gt; elements (either name or href), images and internally contained style attributes</sch:assert>
<sch:assert test="descendant::text()[normalize-space(.)!=''] or descendant::h:img[@src]">txt-2: The narrative SHALL have some non-whitespace content</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:contained/f:meta/f:security">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:contained/f:meta/f:tag">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:identifier/f:type">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:identifier/f:type/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:identifier/f:period">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:identifier/f:assigner">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:unit">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:unit/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:source">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:parent">
<sch:assert test="not(starts-with(f:reference/@value, '#')) or exists(ancestor::f:entry/f:resource/f:*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')]|/*/f:contained/f:*[f:id/@value=substring-after(current()/f:reference/@value, '#')])">ref-1: SHALL have a local reference if the resource is provided inline</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:measurementPeriod/f:repeat">
<sch:assert test="not(exists(f:periodMax)) or exists(period)">tim-6: If there's a periodMax, there must be a period</sch:assert>
<sch:assert test="not(exists(f:durationMax)) or exists(duration)">tim-7: If there's a durationMax, there must be a duration</sch:assert>
<sch:assert test="not(exists(f:duration)) or exists(f:durationUnits)">tim-1: if there's a duration, there needs to be duration units</sch:assert>
<sch:assert test="not(exists(f:period)) or exists(f:periodUnits)">tim-2: if there's a period, there needs to be duration units</sch:assert>
<sch:assert test="not(exists(f:frequency)) or not(exists(f:when))">tim-3: Either frequency or when can exist, not both</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:measurementPeriod/f:repeat/f:bounds">
<sch:assert test="not(exists(f:start)) or not(exists(f:end)) or (f:start/@value &lt;= f:end/@value)">per-1: If present, start SHALL have a lower value than end</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:measurementPeriod/f:repeat/f:duration">
<sch:assert test="@value &gt;= 0 or not(@value)">tim-4: duration SHALL be a non-negative value</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:measurementPeriod/f:repeat/f:period">
<sch:assert test="@value &gt;= 0 or not(@value)">tim-5: period SHALL be a non-negative value</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:measurementPeriod/f:code">
<sch:assert test="count(f:coding[f:primary/@value='true'])&lt;=1">ccc-2: Only one coding in a set can be chosen directly by the user</sch:assert>
</sch:rule>
<sch:rule context="f:DeviceMetric/f:measurementPeriod/f:code/f:coding">
<sch:assert test="not (exists(f:valueSet) and exists(f:code)) or exists(f:system)">cod-1: If a valueSet is provided, a system URI Is required</sch:assert>
</sch:rule>
</sch:pattern>
</sch:schema>

Some files were not shown because too many files have changed in this diff Show More