org.openehealth.ipf.commons.xml.SchematronTransmogrifier Maven / Gradle / Ivy
Show all versions of ipf-commons-xml Show documentation
/*
* Copyright 2009 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openehealth.ipf.commons.xml;
import java.io.StringReader;
import java.util.Map;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.stream.StreamSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Converts a XML document into a Schematron validation report by applying
* Schematron rules. The rules to be used are passed in with the
* {@link #zap(Source, Object...)} call, however, the resulting Xslt Template
* object is cached for subsequent transformations using this stylesheet.
*
* The following standard Schematron parameters can be passed in as Map
* parameter:
*
* - phase : NMTOKEN | "#ALL" (default) Select the phase for validation
*
- allow-foreign : "true" | "false" (default) Pass non-Schematron elements
* and rich markup to the generated stylesheet
*
- diagnose : "true" (default) | "false" Add the diagnostics to the
* assertion test in reports
*
- property : "true" (default) | "false" Experimental: Add properties to the
* assertion test in reports
*
- generate-paths : "true" (default) | "false" Generate the @location
* attribute with XPaths
*
- sch.exslt.imports : semi-colon delimited string of filenames for some
* EXSLT implementations
*
- optimize : "visit-no-attributes" Use only when the schema has no
* attributes as the context nodes
*
- generate-fired-rule: "true" (default) | "false" Generate fired-rule
* elements
*
*
*
* @author Christian Ohr
*/
public class SchematronTransmogrifier extends XsltTransmogrifier {
private final static Logger LOG = LoggerFactory.getLogger(SchematronTransmogrifier.class);
private final XsltTransmogrifier xsltTransmogrifier;
@SuppressWarnings("unchecked")
public SchematronTransmogrifier() {
this((Class) String.class);
}
public SchematronTransmogrifier(Class outputFormat) {
this(new XsltTransmogrifier<>(String.class), outputFormat);
}
public SchematronTransmogrifier(Class outputFormat, Map staticParams) {
this(new XsltTransmogrifier<>(String.class), outputFormat, staticParams);
}
public SchematronTransmogrifier(XsltTransmogrifier t, Class outputFormat) {
super(outputFormat);
xsltTransmogrifier = t;
}
public SchematronTransmogrifier(XsltTransmogrifier t, Class outputFormat, Map staticParams) {
super(outputFormat, staticParams);
xsltTransmogrifier = t;
}
@Override
protected String resourceCacheKey(Object... params) {
String phase = null;
if (params[0] instanceof SchematronProfile) {
var schematronProfile = (SchematronProfile) params[0];
var parameters = schematronProfile.getParameters();
if (parameters != null) {
phase = (String) parameters.get("phase");
}
}
return (phase != null)
? resourceLocation(params) + '\n' + phase
: resourceLocation(params);
}
@Override
protected Templates createResource(Object... params) {
try {
LOG.debug("Creating new Schematron stylesheet");
Source rules = resourceContent(params);
var parameters = resourceParameters(params);
LOG.debug("step 1 of 3");
var source = step(xsltTransmogrifier, rules,
"/schematron/iso_dsdl_include.xsl", parameters);
LOG.debug("step 2 of 3");
source = step(xsltTransmogrifier, source,
"/schematron/iso_abstract_expand.xsl", parameters);
LOG.debug("step 3 of 3");
source = step(xsltTransmogrifier, source,
"/schematron/iso_svrl_for_xslt2.xsl", parameters);
var template = getFactory().newTemplates(source);
LOG.debug("done!");
return template;
} catch (Exception e) {
throw new IllegalArgumentException("The schematron rules resource "
+ resourceLocation(params) + " is not valid", e);
}
}
private static Source step(XsltTransmogrifier t, Source input,
String stylesheet, Map params) {
var s = t.zap(input, stylesheet, params);
return new StreamSource(new StringReader(s));
}
}