ph-schematron/src/main/java/com/helger/schematron/pure/bound/xpath/PSXPathBoundSchema.java
@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 ())
      {
        // The pattern has special variables, so we need to extend the variable
        // 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 ())
        {
          // The rule has special variables, so we need to extend the
          // 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;
  }
@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 ())
      {
        // The pattern has special variables, so we need to extend the variable
        // 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 ())
        {
          // The rule has special variables, so we need to extend the
          // 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;
  }
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