use of com.helger.schematron.pure.binding.xpath.PSXPathVariables in project ph-schematron by phax.
the class PSXPathBoundSchema method _createBoundPatterns.
/**
* Pre-compile all patterns incl. their content
*
* @param aXPathContext
* @param aXPathContext
* Global XPath object to use. May not be <code>null</code>.
* @param aBoundDiagnostics
* A map from DiagnosticID to its mapped counterpart. May not be
* <code>null</code>.
* @param aGlobalVariables
* The global Schematron-let variables. May not be <code>null</code>.
* @return <code>null</code> if an XPath error is contained
*/
@Nullable
private ICommonsList<PSXPathBoundPattern> _createBoundPatterns(@Nonnull final XPath aXPathContext, @Nonnull final ICommonsMap<String, PSXPathBoundDiagnostic> aBoundDiagnostics, @Nonnull final IPSXPathVariables aGlobalVariables) {
final ICommonsList<PSXPathBoundPattern> ret = new CommonsArrayList<>();
boolean bHasAnyError = false;
// For all relevant patterns
for (final PSPattern aPattern : getAllRelevantPatterns()) {
// Handle pattern specific variables
final PSXPathVariables aPatternVariables = aGlobalVariables.getClone();
if (aPattern.hasAnyLet()) {
// map
for (final Map.Entry<String, String> aEntry : aPattern.getAllLetsAsMap().entrySet()) if (aPatternVariables.add(aEntry).isUnchanged())
error(aPattern, "Duplicate <let> with name '" + aEntry.getKey() + "' in <pattern>");
}
// For all rules of the current pattern
final ICommonsList<PSXPathBoundRule> aBoundRules = new CommonsArrayList<>();
for (final PSRule aRule : aPattern.getAllRules()) {
// Handle rule specific variables
final PSXPathVariables aRuleVariables = aPatternVariables.getClone();
if (aRule.hasAnyLet()) {
// variable map
for (final Map.Entry<String, String> aEntry : aRule.getAllLetsAsMap().entrySet()) if (aRuleVariables.add(aEntry).isUnchanged())
error(aRule, "Duplicate <let> with name '" + aEntry.getKey() + "' in <rule>");
}
// For all contained assert and reports within the current rule
final ICommonsList<PSXPathBoundAssertReport> aBoundAssertReports = new CommonsArrayList<>();
for (final PSAssertReport aAssertReport : aRule.getAllAssertReports()) {
final String sTest = aRuleVariables.getAppliedReplacement(aAssertReport.getTest());
try {
final XPathExpression aTestExpr = _compileXPath(aXPathContext, sTest);
final ICommonsList<PSXPathBoundElement> aBoundElements = _createBoundElements(aAssertReport, aXPathContext, aRuleVariables);
if (aBoundElements == null) {
// Error already emitted
bHasAnyError = true;
} else {
final PSXPathBoundAssertReport aBoundAssertReport = new PSXPathBoundAssertReport(aAssertReport, sTest, aTestExpr, aBoundElements, aBoundDiagnostics);
aBoundAssertReports.add(aBoundAssertReport);
}
} catch (final Throwable t) {
error(aAssertReport, "Failed to compile XPath expression in <" + (aAssertReport.isAssert() ? "assert" : "report") + ">: '" + sTest + "' with the following variables: " + aRuleVariables.getAll(), t);
bHasAnyError = true;
}
}
// Evaluate base node set for this rule
final String sRuleContext = aGlobalVariables.getAppliedReplacement(getValidationContext(aRule.getContext()));
PSXPathBoundRule aBoundRule = null;
try {
final XPathExpression aRuleContext = _compileXPath(aXPathContext, sRuleContext);
aBoundRule = new PSXPathBoundRule(aRule, sRuleContext, aRuleContext, aBoundAssertReports);
aBoundRules.add(aBoundRule);
} catch (final XPathExpressionException ex) {
error(aRule, "Failed to compile XPath expression in <rule>: '" + sRuleContext + "'", ex.getCause() != null ? ex.getCause() : ex);
bHasAnyError = true;
}
}
// Create the bound pattern
final PSXPathBoundPattern aBoundPattern = new PSXPathBoundPattern(aPattern, aBoundRules);
ret.add(aBoundPattern);
}
if (bHasAnyError)
return null;
return ret;
}
use of com.helger.schematron.pure.binding.xpath.PSXPathVariables in project ph-schematron by phax.
the class PSXPathBoundSchema method bind.
@Nonnull
public PSXPathBoundSchema bind() throws SchematronBindException {
if (s_aLogger.isDebugEnabled())
s_aLogger.debug("Binding pure Schematron");
if (m_aBoundPatterns != null)
throw new IllegalStateException("bind must only be called once!");
final PSSchema aSchema = getOriginalSchema();
final PSPhase aPhase = getPhase();
// Get all "global" variables that are defined in the schema
final PSXPathVariables aGlobalVariables = new PSXPathVariables();
if (aSchema.hasAnyLet())
for (final Map.Entry<String, String> aEntry : aSchema.getAllLetsAsMap().entrySet()) if (aGlobalVariables.add(aEntry).isUnchanged())
error(aSchema, "Duplicate <let> with name '" + aEntry.getKey() + "' in global <schema>");
if (aPhase != null) {
// Get all variables that are defined in the specified phase
for (final Map.Entry<String, String> aEntry : aPhase.getAllLetsAsMap().entrySet()) if (aGlobalVariables.add(aEntry).isUnchanged())
error(aSchema, "Duplicate <let> with name '" + aEntry.getKey() + "' in <phase> with name '" + getPhaseID() + "'");
}
final XPath aXPathContext = _createXPathContext();
// Pre-compile all diagnostics first
final ICommonsMap<String, PSXPathBoundDiagnostic> aBoundDiagnostics = _createBoundDiagnostics(aXPathContext, aGlobalVariables);
if (aBoundDiagnostics == null)
throw new SchematronBindException("Failed to precompile the diagnostics of the supplied schema. Check the " + (isDefaultErrorHandler() ? "log output" : "error listener") + " for XPath errors!");
// Perform the pre-compilation of all XPath expressions in the patterns,
// rules, asserts/reports and the content elements
m_aBoundPatterns = _createBoundPatterns(aXPathContext, aBoundDiagnostics, aGlobalVariables);
if (m_aBoundPatterns == null)
throw new SchematronBindException("Failed to precompile the supplied schema.");
return this;
}
Aggregations