code: protected function parseRule(RuleCollection $collection, \DOMElement $node, $path)
      {
          if ('' === ($id = $node->getAttribute('id'))) {
              throw new \InvalidArgumentException(sprintf('The <rule> element in file "%s" must have an "id" attribute.', $path));
          }
  
          if ('' === ($expression = $node->getAttribute('expression'))) {
              throw new \InvalidArgumentException(sprintf('The <rule> element in file "%s" must have an "expression" attribute.', $path));
          }
  
          $rule = new Rule($expression);
  
          list($tags) = $this->parseConfigs($node, $path);
  
          foreach ($tags as $tagName => $tagAttrs) {
              $rule->addTag($tagName, $tagAttrs);
          }
  
          $collection->add($id, $rule);
      }
docs: Parses a rule and adds it to the RuleCollection.
  
  @param RuleCollection $collection RuleCollection instance
  @param \DOMElement    $node       Element to parse that represents a Rule
  @param string         $path       Full path of the XML file being processed
  
  @throws \InvalidArgumentException When the XML is invalid