Class: Leptris::XML::Iterparse
- Inherits:
-
Object
- Object
- Leptris::XML::Iterparse
- Defined in:
- lib/leptris/xml/iterparse.rb
Overview
Incremental tree iteration (libleptris v1.6.0): yields each completed TOP-LEVEL child element of the document root as it parses. The previous element's whole subtree is released when the next is produced — memory stays bounded by the largest subtree, not the document.
Leptris::XML::Iterparse.parse(huge_xml) do |element|
process(element) # subtree valid until the next iteration
end
v1 limitation (upstream): element names are the QName as written; namespace prefixes are not re-resolved — use the DOM path when namespace URIs matter. The yielded elements have no parent Document; #document returns nil and they must not outlive the iteration.
Class Method Summary collapse
-
.parse(xml_or_io, &block) ⇒ Object
NOTE: an IO argument is read fully into memory before the C iterator starts — the bounded-memory path is parse_file (C-side file streaming).
- .parse_file(path, &block) ⇒ Object
Instance Method Summary collapse
- #free ⇒ Object
-
#initialize(handle) ⇒ Iterparse
constructor
A new instance of Iterparse.
- #run ⇒ Object
Constructor Details
#initialize(handle) ⇒ Iterparse
Returns a new instance of Iterparse.
35 36 37 38 |
# File 'lib/leptris/xml/iterparse.rb', line 35 def initialize(handle) raise Leptris::XML::ParseError, "leptris_iterparse_new failed" if handle.null? @handle = handle end |
Class Method Details
.parse(xml_or_io, &block) ⇒ Object
NOTE: an IO argument is read fully into memory before the C iterator starts — the bounded-memory path is parse_file (C-side file streaming). The C API takes one (xml, len) buffer.
24 25 26 27 28 |
# File 'lib/leptris/xml/iterparse.rb', line 24 def self.parse(xml_or_io, &block) xml = xml_or_io.respond_to?(:read) ? xml_or_io.read : xml_or_io.to_s iterator = new(Leptris::XML::FFI.leptris_iterparse_new(xml, xml.bytesize)) iterator.run(&block) end |
Instance Method Details
#free ⇒ Object
55 56 57 58 59 |
# File 'lib/leptris/xml/iterparse.rb', line 55 def free return if @handle.nil? Leptris::XML::FFI.leptris_iterparse_free(@handle) @handle = nil end |
#run ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/leptris/xml/iterparse.rb', line 40 def run return enum_for(:run) unless block_given? loop do ptr = Leptris::XML::FFI.leptris_iterparse_next(@handle) break if ptr.null? # document: nil — the subtree belongs to the iterator's pool, # not a long-lived Document, so wrapper caching is skipped and # #document is nil on the yielded elements. yield Leptris::XML::Node.wrap(ptr, nil) end self ensure free end |