protected function elementMatchesRule($element, $rule = null)
    {
        // If the rule doesn't exist at all, the element isn't allowed
        if (!$rule) {
            return false;
        }

        // If the rule has attributes required, check them to see if this element has at least one
        if ($rule->attributesRequired) {
            $hasMatch = false;

            foreach ($rule->attributesRequired as $attr) {
                if ($element->getAttribute($attr)) {
                    $hasMatch = true;
                    break;
                }
            }

            if (!$hasMatch) {
                return false;
            }
        }

        // If the rule says to remove empty elements, and this element is empty, remove it
        if ($rule->removeEmpty && !$element->firstChild) {
            return false;
        }

        // No further tests required, element passes
        return true;
    }