<commit_before>require 'nokogiri'

module Nokogiri

  module XML

    class Node
      
      def matching(other, matcher)
        other_elem = other.at_xpath(path)
        matcher.record(self.path, false, Matcher::Xml::EXISTENCE, Matcher::Xml::NOT_FOUND) unless other_elem
        other_elem
      end
    end

    class Document

      def match?(other, matcher)
        matching(other, matcher) ? true : false
      end

    end

    class Element

      def match?(other, matcher)
        @matcher = matcher
        other_elem = matching(other, matcher)
        return false unless other_elem
        children_match?(other_elem) & attributes_match?(other_elem)
      end

      private

        def children_match?(other)
          match = children.size == other.children.size
          @matcher.record(self.path, match, "#{children.size} children", "#{other.children.size} children")
          match
        end

        def attributes_match?(other)
          match = attributes.size == other.attributes.size
          unless match
            @matcher.record(self.path, match, "#{attributes.size} attributes", "#{other.attributes.size} attributes")
            return false
          end

          attributes.values.each { |attr|  match = match & attr.match?(other, @matcher) }
          match
        end

    end

    class Text

      def match?(other, matcher)
        other_elem = matching(other, matcher)
        return false unless other_elem

        custom_matcher = matcher.custom_matchers[path]
        match = custom_matcher ? custom_matcher.call(other_elem.content) : (content == other_elem.content)
        matcher.record(self.path, match, content, other_elem.content)
        match
      end

    end

    class Attr

      def match?(other, matcher)
        other_elem = matching(other, matcher)
        return false unless other_elem

        custom_matcher = matcher.custom_matchers[path]
        match = custom_matcher ? custom_matcher.call(other_elem.value) : (value == other_elem.value)
        matcher.record(self.path, match, value, other_elem.value)
        match
      end

    end

  end

end<commit_msg>Simplified matching in nokogiri extensions<commit_after>require 'nokogiri'

module Nokogiri

  module XML

    class Node

      def match?(other, matcher)
        @matcher = matcher
        matching(other) ? true : false
      end

      def matching(other)
        other_elem = other.at_xpath(path)
        @matcher.record(self.path, false, Matcher::Xml::EXISTENCE, Matcher::Xml::NOT_FOUND) unless other_elem
        other_elem
      end
      
      def evaluate(path, expected, actual)
        custom_matcher = @matcher.custom_matchers[path]
        match = custom_matcher ? custom_matcher.call(actual) : expected == actual
        @matcher.record(self.path, match, expected, actual)
        match
      end
      
    end

    class Element

      def match?(other, matcher)
        @matcher = matcher
        return false unless other_elem = matching(other)
        children_match?(other_elem) & attributes_match?(other_elem)
      end

      private

        def children_match?(other)
          match = children.size == other.children.size
          @matcher.record(self.path, match, "#{children.size} children", "#{other.children.size} children")
          match
        end

        def attributes_match?(other)
          match = attributes.size == other.attributes.size
          unless match
            @matcher.record(self.path, match, "#{attributes.size} attributes", "#{other.attributes.size} attributes")
            return false
          end

          attributes.values.each { |attr|  match = match & attr.match?(other, @matcher) }
          match
        end

    end

    class Text

      def match?(other, matcher)
        @matcher = matcher
        return false unless other_elem = matching(other)
        evaluate(path, content, other_elem.content)
      end

    end

    class Attr

      def match?(other, matcher)
        @matcher = matcher
        return false unless other_elem = matching(other)
        evaluate(path, value, other_elem.value)
      end

    end

  end

end
{'fraction_non_alphanumeric': 0.08954863625392227, 'fraction_numerical': 0.0, 'mean_word_length': 2.281076801266825, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6182012', 'n_tokens_mistral': 1198, 'n_tokens_neox': 1176, 'n_words': 283}