diff --git a/library/HTMLPurifier.includes.php b/library/HTMLPurifier.includes.php
index e9916de0..97fcf27d 100644
--- a/library/HTMLPurifier.includes.php
+++ b/library/HTMLPurifier.includes.php
@@ -137,6 +137,7 @@ require 'HTMLPurifier/ConfigSchema/Validator/Alnum.php';
require 'HTMLPurifier/ConfigSchema/Validator/Composite.php';
require 'HTMLPurifier/ConfigSchema/Validator/Exists.php';
require 'HTMLPurifier/ConfigSchema/Validator/NamespaceExists.php';
+require 'HTMLPurifier/ConfigSchema/Validator/Or.php';
require 'HTMLPurifier/ConfigSchema/Validator/ParseId.php';
require 'HTMLPurifier/ConfigSchema/Validator/ParseType.php';
require 'HTMLPurifier/ConfigSchema/Validator/Unique.php';
diff --git a/library/HTMLPurifier/ConfigSchema/Validator/Or.php b/library/HTMLPurifier/ConfigSchema/Validator/Or.php
new file mode 100644
index 00000000..fc818b64
--- /dev/null
+++ b/library/HTMLPurifier/ConfigSchema/Validator/Or.php
@@ -0,0 +1,39 @@
+validators[] = $validator;
+ }
+
+ public function validate(&$arr, $interchange) {
+ $exceptions = array();
+ $pass = false;
+ foreach ($this->validators as $validator) {
+ try {
+ $validator->validate($arr, $interchange);
+ } catch (HTMLPurifier_ConfigSchema_Exception $e) {
+ $exceptions[] = $e;
+ continue;
+ }
+ $exceptions = array();
+ break;
+ }
+ if ($exceptions) {
+ // I wonder how we can make the exceptions "lossless"
+ throw new HTMLPurifier_ConfigSchema_Exception('All validators failed: ' . implode(";\n", $exceptions));
+ }
+ }
+
+}
diff --git a/tests/HTMLPurifier/ConfigSchema/Validator/OrTest.php b/tests/HTMLPurifier/ConfigSchema/Validator/OrTest.php
new file mode 100644
index 00000000..d8718ff5
--- /dev/null
+++ b/tests/HTMLPurifier/ConfigSchema/Validator/OrTest.php
@@ -0,0 +1,31 @@
+ 'RD');
+ $this->validator->addValidator(new HTMLPurifier_ConfigSchema_Validator_Alnum('ID'));
+ // Never called:
+ $this->validator->addValidator(new HTMLPurifier_ConfigSchema_Validator_Exists('ALT-ID'));
+ $this->validator->validate($arr, $this->interchange);
+ }
+
+ public function testValidatePassLater() {
+ $arr = array('ID' => 'RD');
+ // This one fails:
+ $this->validator->addValidator(new HTMLPurifier_ConfigSchema_Validator_Exists('ALT-ID'));
+ // But this one passes:
+ $this->validator->addValidator(new HTMLPurifier_ConfigSchema_Validator_Alnum('ID'));
+ $this->validator->validate($arr, $this->interchange);
+ }
+
+ public function testValidateFail() {
+ $arr = array('ID' => 'RD');
+ $this->validator->addValidator(new HTMLPurifier_ConfigSchema_Validator_Exists('ALT-ID'));
+ $this->validator->addValidator(new HTMLPurifier_ConfigSchema_Validator_Exists('FOOBAR'));
+ $this->expectException('HTMLPurifier_ConfigSchema_Exception');
+ $this->validator->validate($arr, $this->interchange);
+ }
+
+}