Module: Goldendocx::XmlSerializers::Nokogiri

Defined in:
lib/goldendocx/xml_serializers/nokogiri.rb

Constant Summary collapse

DEFAULT_BUILD_OPTIONS =
::Nokogiri::XML::Node::SaveOptions.new.tap do |options|
  options.default_xml
  options.no_declaration
end

Class Method Summary collapse

Class Method Details

.build_document(tag, namespaces = [], ignore_namespaces = []) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/goldendocx/xml_serializers/nokogiri.rb', line 43

def build_document(tag, namespaces = [], ignore_namespaces = [])
  ::Nokogiri::XML('<?xml version="1.0" encoding="UTF-8" standalone="yes"?>').tap do |root|
    root << ::Nokogiri::XML::Node.new(tag, root).tap do |document|
      Goldendocx::NAMESPACES.slice(*namespaces).each do |key, namespace|
        document.add_namespace key.to_s, namespace
      end
      document['mc:Ignorable'] = ignore_namespaces.join(' ') unless ignore_namespaces.empty?

      yield(document) if block_given?
    end
  end
end

.build_document_xml(tag, namespaces = [], ignore_namespaces = []) ⇒ Object



39
40
41
# File 'lib/goldendocx/xml_serializers/nokogiri.rb', line 39

def build_document_xml(tag, namespaces = [], ignore_namespaces = [], &)
  CGI.unescapeHTML build_document(tag, namespaces, ignore_namespaces, &).to_xml(indent: 0).delete("\n")
end

.build_element(tag, parent: nil) ⇒ Object



56
57
58
59
60
61
# File 'lib/goldendocx/xml_serializers/nokogiri.rb', line 56

def build_element(tag, parent: nil)
  parent ||= ::Nokogiri::XML('<?xml version="1.0"')
  ::Nokogiri::XML::Node.new(tag.to_s, parent).tap do |element|
    yield(element) if block_given?
  end
end

.build_xml(tag) ⇒ Object



35
36
37
# File 'lib/goldendocx/xml_serializers/nokogiri.rb', line 35

def build_xml(tag, &)
  CGI.unescapeHTML build_element(tag, &).to_xml(indent: 0, save_with: DEFAULT_BUILD_OPTIONS).delete("\n")
end

.parse(xml) ⇒ Object

TODO: Nokogiri namespace is soooo strict.… TODO: To read nokogiri source codes and try to understand how it works



16
17
18
19
20
21
22
23
24
25
# File 'lib/goldendocx/xml_serializers/nokogiri.rb', line 16

def parse(xml)
  document = ::Nokogiri::XML(xml)

  missing_namespaces = document.errors.filter_map do |error|
    error.str1 if error.message.match?('Namespace.*not defined')
  end.uniq.compact
  return document if missing_namespaces.blank?

  wrap_document(document, missing_namespaces)
end

.search(node, paths) ⇒ Object



27
28
29
30
31
32
33
# File 'lib/goldendocx/xml_serializers/nokogiri.rb', line 27

def search(node, paths)
  return node if paths.blank?

  search_paths = paths.map { |path| path.include?(':') || path == '*' ? path : ['xmlns', path].join(':') }
  namespaces = node.namespaces.merge(node.document.namespaces)
  node.xpath(search_paths.join('/'), namespaces)
end