iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
Run the original Schematron validator and your PHP port against the same test documents, then compare their structured results rule by rule. A passing suite supports equivalence only for the schema revision, Schematron features, runtime, and cases you actually tested; it does not prove universal conformance.
Decide what “correct” means before testing
Schematron expresses rules and assertions about XML, commonly using XPath. In the legacy XSLT skeleton workflow, a Schematron schema is compiled into XSLT, which then validates an XML document and can emit an SVRL report. SVRL is a structured way to report validation results, not merely a pass/fail message. See the Schematron documentation and the SVRL specification information.
Write down the comparison contract for your port. Record the source .sch revision, declared Schematron edition, query binding, active phase, included resources, namespace declarations, and any extension functions. Also pin the PHP version and XML API used. Then decide which outputs consumers depend on:
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11- Overall valid or invalid outcome.
- Which rules fired and which assertions failed.
- Severity or flags, messages, diagnostics, and locations.
- Successful-report entries and any ordering that downstream code treats as significant.
- How malformed XML and parser errors are reported, separately from Schematron failures.
If the original exposes SVRL but the PHP port returns only a boolean, the port may be adequate for a narrowly defined caller, but it has not reproduced the original reporting contract.
#1 Best Overall
Build paired fixtures for each rule
For every assertion or rule, create at least one small XML document expected to pass and one expected to fail. Keep each fixture, its expected result, and the relevant rule identifier together. For conditional or cross-field rules, vary one condition at a time so a mismatch points to a specific behavior rather than a large document with many interacting changes.
A useful starting example is a rule requiring a particular element: test a document where it is present and one where it is absent. If the rule also depends on a namespace or a relationship between two fields, add separate fixtures for those conditions instead of relying on one complex failure case.
Rank #2
Include cases that exercise the features your schema uses:
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errors- Required and forbidden elements or attributes; empty, whitespace-only, and populated text.
- Value patterns, code-list membership, conditional presence, and relationships between fields.
- Namespaced elements and attributes, including namespace-prefix handling.
- Context selection, nested nodes, XPath axes, and predicates.
- Every supported phase and include path; abstract patterns or rules, diagnostics, severity, flags, and extensions where applicable.
- Malformed XML and parser errors, tracked separately from validation assertions.
These are practical test dimensions, not a formal conformance suite. A domain-specific example is the NEMSIS Technical Assistance Center’s Schematron Development Kit guide, which describes generating XML test cases that pass or fail specific rules and comparing expected and actual reports.
Run both validators on identical inputs
- Choose a reference engine. Confirm its Schematron edition, query binding, and feature support. Do not assume that any implementation is authoritative for every schema.
- Run the same schema and fixture through both systems. Keep the schema revision, XML bytes, phase, and relevant options identical.
- Compare structured results. Compare validity and, where contractual, fired rules, failed assertions, messages, diagnostics, severity, and locations. Normalize serialization only where it is safe: if report order does not matter to consumers, compare equivalent entries rather than raw bytes; do not normalize away meaningful differences.
- Save mismatches as regressions. Preserve the smallest reproducing XML document, the rule identifier, both outputs, and the decision to fix or accept the difference. Rerun the suite after changes and on every supported PHP/runtime combination.
This differential method can be illustrated with two results for one fixture: both validators should report the same assertion as failed, with the same severity and message if those fields are part of your contract. A matching top-level “invalid” result alone would miss a discrepancy if the PHP version failed a different rule or reported a different location.
Test namespaces and XPath behavior explicitly
Schematron XPath prefixes need namespace declarations, commonly expressed with sch:ns. A PHP XPath evaluator also needs namespace registration before evaluating prefixed expressions. The ISO Schematron specification describes Schematron namespace declarations; PHP documents namespace registration for DOMXPath.
Rank #4
Include fixtures where the same local element name appears in different namespaces, and where a prefixed expression selects the intended namespace. This catches a common false match: treating XML prefixes as if they were part of an element’s identity, or ignoring the namespace URI altogether.
Account for the actual PHP XML API
- DOMXPath evaluates XPath 1.0 and supports namespace registration. Confirm the extension and installed PHP version in the production environment.
- PHP 8.4 introduced DomXPath, documented as a modern equivalent of DOMXPath. Test the chosen class rather than assuming runtime parity.
- XMLReader is a forward-only pull parser. If the port is streaming while the original operates over a tree, verify that context selection and navigation produce equivalent behavior; a cursor-based implementation may need additional machinery.
- PHP 8.5 changes how SimpleXMLElement::xpath() handles scalar-returning expressions such as booleans and numbers. Test result types on the exact production version if your port relies on that API.
Keep the equivalence claim within the supported scope
The Schematron project identifies the fourth edition as ISO Schematron 2025, with additions including XQuery 3.1 and XSLT 3.1 bindings, plus constructs such as group, library, rules, typed let, and severity features. A port targeting an older feature set should state what it excludes rather than implying support based on the .sch file extension alone. See the Schematron project’s edition information.
The legacy XSLT skeleton project documents conformance limitations and notes that it was not conformant to all ISO requirements as of October 2020; the project recommends considering SchXslt for new applications. Other implementations exist, including a Java Schematron library, but their edition, bindings, extensions, and report behavior must be checked against your schema before using one as an oracle.
A precise result statement is more useful than “the rewrite is fully compatible”: for example, say that the PHP implementation matched a named engine for a specific schema revision and feature subset over a stated set of fixtures, including the namespace, phase, and diagnostic cases exercised. The test suite gives evidence about those cases; it is not mathematical proof or, by itself, a complete standards-conformance assessment.
Quick Recap
Verification checklist
- Schema revision, edition, binding, phase, includes, namespaces, and extensions are recorded.
- PHP version and XML API are pinned and tested in the deployment environment.
- Each assertion has at least one passing and one failing fixture, plus targeted edge cases.
- Both implementations receive identical inputs and configuration.
- Comparisons cover every output field the application relies on, not just validity.
- Every resolved mismatch becomes a permanent regression case.
- The final compatibility statement names the tested scope and avoids claiming more than the suite establishes.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

