Class: Edgar::XBRL::XBRL

Inherits:
Object
  • Object
show all
Defined in:
lib/edgar/xbrl/xbrl.rb

Overview

Parses XBRL XML documents for financial fact extraction.

Direct Known Subclasses

InlineXBRL

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(xml_content) ⇒ XBRL

Returns a new instance of XBRL.



11
12
13
14
# File 'lib/edgar/xbrl/xbrl.rb', line 11

def initialize(xml_content)
  @raw = xml_content
  @doc = parse_document(xml_content)
end

Instance Attribute Details

#rawObject (readonly)

Returns the value of attribute raw.



9
10
11
# File 'lib/edgar/xbrl/xbrl.rb', line 9

def raw
  @raw
end

Instance Method Details

#context_refsObject



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/edgar/xbrl/xbrl.rb', line 16

def context_refs
  @doc.css("context").map do |ctx|
    id = ctx["id"]
    entity = ctx.at_css("entity")
    period = ctx.at_css("period")
    start_el = period&.at_css("startDate")
    end_el = period&.at_css("endDate")
    instant_el = period&.at_css("instant")
    # Detect segment dimensions (product/service, geographic, etc.)
    segment = entity&.at_css("segment")
    {
      id: id,
      entity: entity&.text&.strip,
      start_date: start_el&.text&.strip,
      end_date: end_el&.text&.strip,
      instant: instant_el&.text&.strip,
      segmented: !segment.nil?
    }
  end
end

#factsObject



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/edgar/xbrl/xbrl.rb', line 37

def facts
  xbrl_elements = @doc.xpath("//*[local-name() != 'context' and local-name() != 'unit' and local-name() != 'schemaRef' and local-name() != 'linkbaseRef']").select do |el|
    ns = el.namespace
    ns&.href&.include?("xbrl")
  end
  xbrl_elements.map do |el|
    {
      name: el.name,
      namespace: el.namespace&.href,
      value: el.text.strip,
      context_ref: el["contextRef"],
      unit_ref: el["unitRef"],
      decimals: el["decimals"],
      signature: el["signature"]
    }
  end
end

#financial_conceptsObject



61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/edgar/xbrl/xbrl.rb', line 61

def financial_concepts
  ns_prefixes = @doc.namespaces.select { |_, v| v&.include?("us-gaap") || v&.include?("dei") }
  return [] if ns_prefixes.empty?

  financial_ns = ns_prefixes.map { |k, _| k.sub("xmlns:", "") }
  xpath_expr = financial_ns.map { |p| "//#{p}:*" }.join(" | ")
  @doc.xpath(xpath_expr).filter_map do |el|
    next unless el["contextRef"]

    {
      name: el.name,
      value: el.text.strip,
      context_ref: el["contextRef"],
      unit_ref: el["unitRef"],
      decimals: el["decimals"]
    }
  end
end

#to_sObject



80
81
82
# File 'lib/edgar/xbrl/xbrl.rb', line 80

def to_s
  "#<XBRL facts=#{facts.length}>"
end

#unitsObject



55
56
57
58
59
# File 'lib/edgar/xbrl/xbrl.rb', line 55

def units
  @doc.css("unit").map do |u|
    { id: u["id"], measure: u.at_css("measure")&.text&.strip }
  end
end