PHPackages                             milo/schematron - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. milo/schematron

ActiveLibrary

milo/schematron
===============

Implementation of ISO Schematron with Schematron 1.5 back compatibility. Library does not need any XSLT.

v1.0.1(12y ago)18363.6k↓15.6%9[1 issues](https://github.com/milo/schematron/issues)[2 PRs](https://github.com/milo/schematron/pulls)3BSD-3-ClausePHPPHP &gt;=5.3.0

Since Jul 22Pushed 2y ago3 watchersCompare

[ Source](https://github.com/milo/schematron)[ Packagist](https://packagist.org/packages/milo/schematron)[ RSS](/packages/milo-schematron/feed)WikiDiscussions master Synced 1mo ago

READMEChangelogDependencies (1)Versions (4)Used By (3)

[Schematron](https://github.com/milo/schematron/blob/master/src/Schematron.php)
===============================================================================

[](#schematron)

This library is an implementation of the [ISO Schematron](http://www.schematron.com/spec.html) (with Schematron 1.5 back compatibility). It is done by pure DOM processing and does not require any XSLT sheets nor XSLT PHP extension. It was a requirement for a development.

Usage
=====

[](#usage)

Install the Schematron by the Composer or download a release package.

```
require 'src/Schematron.php';

use Milo\Schematron;

$schematron = new Schematron;
$schematron->load('schema.xml');

$document = new DOMDocument;
$document->load('document.xml');
$result = $schematron->validate($document);

var_dump($result);
```

Format of the `Schematron::validate()` result depends on its second argument. E.g. an imaginary results:

```
# Flat array of failed asserts and successful reports (it is default)
$result = $schematron->validate($document, Schematron::RESULT_SIMPLE);
# array (2)
#    0 => "Person must have surname."
#    1 => "Phone number is required."

# More complex structure
$result = $schematron->validate($document, Schematron::RESULT_COMPLEX);
# array (3)
#    0 => stdClass (2)
#       title => "Pattern 1" (9)
#       rules => array (3)
#          2 => stdClass (2)
#             context => "/"
#             errors => array (2)
#                0 => stdClass (3)
#                |  test => "false()" (7)
#                |  message => "S5 - fail" (9)
#                |  path => "/"
#                1 => stdClass (3)
#                   test => "true()" (6)
#                   message => "S6 - fail" (9)
#                   path => "/"

# Or throws exception of first error occurence
try {
    $result = $schematron->validate($document, Schematron::RESULT_EXCEPTION);
} catch (Milo\SchematronException $e) {
    echo $e->getMessage();  # Person must have surname.
}
```

A validation phase can be passed by 3rd argument:

```
$schematron->validate($document, Schematron::RESULT_SIMPLE, 'phase-base-rules');
```

Schematron performs a schema namespace (ISO or v1.5) autodetection but the namespace can be passed manually:

```
$schematron = new Schmeatron(Schematron::NS_ISO);
```

By `Schematron::setOptions($options)` you can adjust the Schematron behaviour. The $options is a mask of following flags:

```
# Allows to schema does not contain a  element,
# so s stands alone in XML, e.g. in Relax NG schema
Schematron::ALLOW_MISSING_SCHEMA_ELEMENT

#  are ignored and do not expand
Schematron::IGNORE_INCLUDE

#  are forbidden and loading fails if occures
Schematron::FORBID_INCLUDE

#  with the same @context as any rule before is skipped
# This arises from official Universal Tests (http://www.schematron.com/validators/universalTests.sch)
Schematron::SKIP_DUPLICIT_RULE_CONTEXT

#  needn't to contain s
Schematron::ALLOW_EMPTY_SCHEMA

#  needn't to contain s
Schematron::ALLOW_EMPTY_PATTERN

#  needn't to contain s nor s
Schematron::ALLOW_EMPTY_RULE
```

An `` processing is affected by setting `Schematron::setAllowedInclude($allowed)` mask which permits types of include uri and `Schematron::setMaxIncludeDepth($depth)`:

```
# Remote URLs
Schematron::INCLUDE_URL

# Absolute and relative filesystem paths
Schematron::INCLUDE_ABSOLUTE_PATH
Schematron::INCLUDE_RELATIVE_PATH

# Any URI
Schematron::INCLUDE_ALL
```

And two basic attributes of loaded schema are accesible over:

```
$schematron->getSchemaVersion();
$schematron->getSchemaTitle();
```

Licence
=======

[](#licence)

You may use all files under the terms of the New BSD Licence, or the GNU Public Licence (GPL) version 2 or 3, or the MIT Licence.

Tests
=====

[](#tests)

The Schematron tests are written for [Nette Tester](https://github.com/nette/tester). Two steps are required to run them:

```
# Download the Tester tool
composer.phar update --dev

# Run the tests
vendor/bin/tester tests
```

---

[![Build Status](https://camo.githubusercontent.com/6ffda42475f96b76c644a8b077a274c1a504a3efe4a60054d3c5025c221c3c56/68747470733a2f2f7472617669732d63692e6f72672f6d696c6f2f736368656d6174726f6e2e706e673f6272616e63683d6d6173746572)](https://travis-ci.org/milo/schematron)

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance19

Infrequent updates — may be unmaintained

Popularity44

Moderate usage in the ecosystem

Community19

Small or concentrated contributor base

Maturity60

Established project with proven stability

 Bus Factor1

Top contributor holds 90.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~258 days

Total

2

Last Release

4424d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/a4c732343c0eba814891adfe91dea1754265ea7a5cbed1232d872cac406ff21e?d=identicon)[milonemilo](/maintainers/milonemilo)

---

Top Contributors

[![milo](https://avatars.githubusercontent.com/u/439140?v=4)](https://github.com/milo "milo (10 commits)")[![Awnage](https://avatars.githubusercontent.com/u/368749?v=4)](https://github.com/Awnage "Awnage (1 commits)")

### Embed Badge

![Health badge](/badges/milo-schematron/health.svg)

```
[![Health](https://phpackages.com/badges/milo-schematron/health.svg)](https://phpackages.com/packages/milo-schematron)
```

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
