Tools for Schema & Schematron Validation and Stylesheet Transformation





1.00/5 (1 vote)
XML schema Schematron and stylesheet transformation
1. Introduction
When working with the NHS projects, I need to deal with a large number of linked schemas and create a package to validate messages against that schema. The NuGet package I created called Messaging.Core
. Though there are some resources related to the NHS project, overall, the code can be used for other domains of application as well.
2. How to Use Messaging.Core Package
For how to use Messaging.Core
in the code, you can see the unit tests in Github. This article will describe the component in the package and how to use them. The Messaging.Core
contains a number of artifacts:
2.1 Resource Resolver
Namespace: Messaging.Resolvers
The package has resolvers that can resolve resources from either an assembly or from a directory. The resource resolver is inherited from XmlUrlResolver
, IResourceResolver
. The IResourceResolver
has a method with a signature, Stream GetResourceStream(string resourceName)
, which resolves a resource given its name. When working with resource resolvers, the resource name is assumed to have two parts: name and extension. There are two types of resource resolvers in Messaging.Core
package.
2.1.1. EmbeddedResourceResolver
Signatures:
public EmbeddedResourceResolver(Assembly resourceAssembly = null)
public static EmbeddedResourceResolver Create(AssemblyType assemblyType)
public Stream GetResourceStream(string resourceName)
public object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
As the name implied, this resource resolver locates a resource as an embedded resource in an assembly. The instance constructor takes an assembly as the optional argument, and it will default to the current assembly if the argument is null
. The static
constructor takes enumerated AssemblyType
, which can have a value of:
AssemblyType.Caller
, the assembly which callsMessaging.Core
method. This value can be used for unit testing where the resources normally reside within the unit test project.AssemblyType.Library
, theMessaging.Core
assembly itself. This can be used to resolve resources that reside on theMessaging.Core
project.AssemblyType.EntryHost
, the host assembly which executes the code on runtime, like console or web app projects.
If you use this resource resolver, you can use either package 1-4 assembly to validate a message against a schema in those packages. For the EmbeddedResourceResolver
, locates embedded resources in the assembly based on the resources name and ignoring the path.
GetResourceStream
method is part of IResourceResolver
and can be used to resolve a resource name to a content stream. The package provides an extension method GetText
to convert the stream
to string
content. GetEntity
method is part of XmlUrlResolver
, and normally used by other methods using XmlUrlResolver
such as for schema validation, and it is not recommended to use it directly.
2.1.2. DirectoryResourceResolver
Signatures:
public DirectoryResourceResolver(string path)
public Stream GetResourceStream(string resourceName)
public object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
If you use this resource resolver, you can validate a message against schema in a directory. The constructor takes the directory path as an argument. In order to use DirectoryResourceResolver
, you just need to put DMS schemas or any other schema in a directory and validate a message against that directory. The resolver will locate resources based on the resource name, it does not matter where you put the resource in the directory, as long as they are all unique in that directory. The last two methods are the same as those of AssemblyResourceResolver
.
3.2. Stylesheet Transformer
Namespace: Messaging.Transformers
Signatures:
public StylesheetTransformer(ResourceResolver resolver = null)
public string Transform(string stylesheetXml, string inputXml)
public Stream TransformStream(Stream stylesheetStream, Stream inputXmlStream)
The constructor takes an optional resource resolver and is used to resolve stylesheet references. You don't need one if working with a single stylesheet without any references. It has two Transform
methods and a TransformStream
method.
The first Transform
method takes a stylesheet XML and an input XML, and if there are references in the stylesheet XML, it uses the resource resolver passed in the constructor to resolve the resources. The second Transform
method takes an enumerated stylesheet in the Messaging.Core
and an input XML. The enumerated stylesheet is specific to NHS projects, and may not be useful for general usage.
The last method, TransformStream
, takes stream
instead of raw XML for both stylesheet and input XML. There is an extension method in the Messaging.Core
that converts from raw XML into a stream
called GetStream
.
3.3. SchemaValidator
Namespace: Messaging.Validators
Signatures:
public SchemaValidator(ResourceResolver externalResolver)
public static SchemaValidator Create(Assembly externalAssembly)
public static SchemaValidator Create(string folder)
public Result Validate(string schemaName, string inputXml)
public Result Validate(Stream schemaStream, Stream inputXmlStream)
The schema validator has a constructor that takes a resource resolver and also two static
constructors that take either a folder path (uses DirectoryResourceResolver) or an assembly (use EmbeddedResourceResolver
).
The first Validate
method takes a schema name and input XML. The schema name is resolved to a resource by the resource resolver passed in the constructor. The schema name is the name of the schema with or without an xsd extension, for example, it can be COCD_TP146045UK05Author2
or COCD_TP146045UK05Author2.xsd. If you have a single schema resource, you can convert it to a stream, e.g., using GetStream
method, and use the second Validate
method which takes a schema stream instead.
The return of Validate
method is Result
, which contains boolean Status
, a string Description
, and optionally an Exception
.
3.4. SchematronValidator
Namespace: Messaging.Validators
Signatures:
public SchematronValidator(string schematronContent, bool convertToIsoNamespace = false)
public SchematronValidator(Stream schematronStream)
public static SchematronValidator Create(SchematronDocument schematronDocument)
public Result Validate(string inputXml)
public Result Validate(Stream inputStream)
SchematronValidator
is an iso Schematron compliant validator. It has two instance constructor and one static constructor. The first instance constructor takes a Schematron content XML and a flag convertToIsoNamespace
. The flag is used to indicate whether or not to convert the namespace in the Schematron content if the old XML namespace is found. The old Schematron content has an XML namespace 'http://www.ascc.net/xml/schematron
', while the new Schematron content has an XML namespace of 'http://purl.oclc.org/dsdl/schematron
'. Without the conversion, the validator will fail to validate a message if the old Schematron content is passed in the constructor. The static
constructor takes an enumerated Schematron content which is located in the Messaging.Core
assembly. The enumerated Schematron is NHS specific and may not be useful for general usage.
In order to validate an XML message against the Schematron content, use Validate
method. It has two variants. The first variant takes a raw XML while the other takes a stream
.
As a side note, the Messaging.Core
can be used with any other domain applications. It can be used with any complex schema or a simple one. In order to use a directory resource resolver, you can just put all your schema in a directory, and create a DirectoryResourceResolver
object passing the directory to the constructor, and then you are on your way to use validators and transformer in Messaging.Core
.
Alternatively, you can put all your schema in an assembly as embedded resources and create an EmbeddedResourceResolver
object by passing the assembly in the constructor. Alternatively, you can implement your own resolver, implementing ResourceResolver
.
History
- 15th February, 2021: Initial version