saxerator 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. data/README.md +16 -1
  2. data/lib/saxerator/builder/array_element.rb +7 -0
  3. data/lib/saxerator/builder/hash_builder.rb +49 -0
  4. data/lib/saxerator/builder/hash_element.rb +13 -0
  5. data/lib/saxerator/builder/string_element.rb +14 -0
  6. data/lib/saxerator/builder/xml_builder.rb +36 -0
  7. data/lib/saxerator/builder.rb +19 -0
  8. data/lib/saxerator/configuration.rb +14 -0
  9. data/lib/saxerator/document_fragment.rb +0 -3
  10. data/lib/saxerator/dsl.rb +17 -6
  11. data/lib/saxerator/full_document.rb +1 -3
  12. data/lib/saxerator/{parser/document_latch.rb → latches/abstract_latch.rb} +2 -4
  13. data/lib/saxerator/{parser/at_depth_latch.rb → latches/at_depth.rb} +2 -2
  14. data/lib/saxerator/{parser/child_of_latch.rb → latches/child_of.rb} +2 -2
  15. data/lib/saxerator/{parser/for_tags_latch.rb → latches/for_tags.rb} +3 -3
  16. data/lib/saxerator/latches/with_attributes.rb +24 -0
  17. data/lib/saxerator/{parser/within_latch.rb → latches/within.rb} +2 -2
  18. data/lib/saxerator/parser/accumulator.rb +2 -3
  19. data/lib/saxerator/parser/latched_accumulator.rb +0 -2
  20. data/lib/saxerator/version.rb +1 -1
  21. data/lib/saxerator.rb +21 -9
  22. data/spec/fixtures/nested_elements.xml +2 -2
  23. data/spec/lib/builder/hash_builder_spec.rb +37 -0
  24. data/spec/lib/builder/xml_builder_spec.rb +37 -0
  25. data/spec/lib/dsl/for_tags_spec.rb +4 -0
  26. data/spec/lib/dsl/with_attributes_spec.rb +32 -0
  27. data/spec/lib/saxerator_spec.rb +13 -31
  28. data/spec/spec_helper.rb +6 -0
  29. data/spec/support/fixture_file.rb +5 -0
  30. metadata +23 -11
  31. data/lib/saxerator/hash_element.rb +0 -11
  32. data/lib/saxerator/parser/with_attribute_latch.rb +0 -25
  33. data/lib/saxerator/string_element.rb +0 -12
  34. data/lib/saxerator/xml_node.rb +0 -46
data/README.md CHANGED
@@ -28,7 +28,7 @@ for added clarity).
28
28
  | `within(name)` | Elements nested anywhere within an element with the given `name`
29
29
  | `child_of(name)` | Elements that are direct children of an element with the given `name`
30
30
  | `with_attribute(name, value)` | Elements that have an attribute with a given `name` and `value`. If no `value` is given, matches any element with the specified attribute name present
31
-
31
+ | `with_attributes(attrs)` | Similar to `with_attribute` except takes an Array or Hash indicating the attributes to match
32
32
 
33
33
  Examples
34
34
  --------
@@ -77,6 +77,21 @@ magazines.each do |magazine|
77
77
  end
78
78
  ```
79
79
 
80
+ Configuration
81
+ -------------
82
+
83
+ Certain options are available at parser initialization.
84
+
85
+ ```ruby
86
+ Saxerator.parse(xml) do |config|
87
+ # config object has accessors for various settings
88
+ end
89
+ ```
90
+
91
+ | Config Option | Default | Values | Description
92
+ |:--------------|:--------|---------------|------------
93
+ | `output_type` | `:hash` | `:hash, :xml` | The type of object generated by Saxerator's parsing. `:hash` should be self-explanatory, `:xml` generates a `Nokogiri::XML::Document`
94
+
80
95
  Known Issues
81
96
  ------------
82
97
  * JRuby closes the file stream at the end of parsing, therefor to perform multiple operations
@@ -0,0 +1,7 @@
1
+ module Saxerator
2
+ module Builder
3
+ class ArrayElement < Array
4
+ attr_accessor :name
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,49 @@
1
+ module Saxerator
2
+ module Builder
3
+ class HashBuilder
4
+ attr_reader :name
5
+
6
+ def initialize(config, name, attributes)
7
+ @config = config
8
+ @name = name
9
+ @attributes = attributes
10
+ @children = []
11
+ @text = false
12
+ end
13
+
14
+ def add_node(node)
15
+ @text = true if node.is_a? String
16
+ @children << node
17
+ end
18
+
19
+ def to_s
20
+ StringElement.new(@children.join, @name, @attributes)
21
+ end
22
+
23
+ def to_hash
24
+ hash = HashElement.new(@name, @attributes)
25
+
26
+ @children.each do |child|
27
+ name = child.name
28
+ element = child.block_variable
29
+
30
+ if hash[name]
31
+ if !hash[name].is_a?(Array)
32
+ hash[name] = ArrayElement[hash[name]]
33
+ hash[name].name = name
34
+ end
35
+ hash[name] << element
36
+ else
37
+ hash[name] = element
38
+ end
39
+ end
40
+
41
+ hash
42
+ end
43
+
44
+ def block_variable
45
+ @text ? to_s : to_hash
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,13 @@
1
+ module Saxerator
2
+ module Builder
3
+ class HashElement < Hash
4
+ attr_accessor :attributes
5
+ attr_accessor :name
6
+
7
+ def initialize(name, attributes)
8
+ self.name = name
9
+ self.attributes = attributes
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module Saxerator
2
+ module Builder
3
+ class StringElement < String
4
+ attr_accessor :attributes
5
+ attr_accessor :name
6
+
7
+ def initialize(str, name, attributes)
8
+ self.name = name
9
+ self.attributes = attributes
10
+ super(str)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,36 @@
1
+ module Saxerator
2
+ module Builder
3
+ class XmlBuilder
4
+ attr_reader :name
5
+
6
+ def initialize(config, name, attributes)
7
+ @config = config
8
+ @name = name
9
+ @attributes = attributes
10
+ @children = []
11
+ @text = false
12
+ end
13
+
14
+ def add_node(node)
15
+ @text = true if node.is_a? String
16
+ @children << node
17
+ end
18
+
19
+ def to_xml(builder)
20
+ if @text
21
+ builder.send("#{name}_", @attributes, @children.join)
22
+ else
23
+ builder.send("#{name}_", @attributes) do |xml|
24
+ @children.each { |child| child.to_xml(xml) }
25
+ end
26
+ end
27
+ end
28
+
29
+ def block_variable
30
+ builder = Nokogiri::XML::Builder.new
31
+ to_xml(builder)
32
+ builder.doc
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,19 @@
1
+ module Saxerator
2
+ module Builder
3
+ extend self
4
+
5
+ def valid?(type)
6
+ Builder.const_defined? "#{camel_case(type)}Builder"
7
+ end
8
+
9
+ def to_class(type)
10
+ Builder.const_get("#{camel_case(type)}Builder")
11
+ end
12
+
13
+ def camel_case(str)
14
+ str = str.to_s
15
+ return str if str !~ /_/ && str =~ /[A-Z]+.*/
16
+ str.split('_').map{|e| e.capitalize}.join
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,14 @@
1
+ module Saxerator
2
+ class Configuration
3
+ attr_reader :output_type
4
+
5
+ def initialize
6
+ @output_type = :hash
7
+ end
8
+
9
+ def output_type=(val)
10
+ raise ArgumentError.new("Unknown output_type '#{val.inspect}'") unless Builder.valid?(val)
11
+ @output_type = val
12
+ end
13
+ end
14
+ end
@@ -1,6 +1,3 @@
1
- require 'saxerator/dsl'
2
- require 'nokogiri'
3
-
4
1
  module Saxerator
5
2
  class DocumentFragment
6
3
  include Enumerable
data/lib/saxerator/dsl.rb CHANGED
@@ -5,24 +5,35 @@ module Saxerator
5
5
  end
6
6
 
7
7
  def for_tags(tags)
8
- raise ArgumentError('#for_tags requires an Array argument') unless tags.is_a? Array
9
- specify Parser::ForTagsLatch.new(tags.map(&:to_s))
8
+ raise ArgumentError.new('#for_tags requires an Array argument') unless tags.is_a? Array
9
+ specify Latches::ForTags.new(tags.map(&:to_s))
10
10
  end
11
11
 
12
12
  def at_depth(depth)
13
- specify Parser::AtDepthLatch.new(depth.to_i)
13
+ specify Latches::AtDepth.new(depth.to_i)
14
14
  end
15
15
 
16
16
  def within(tag)
17
- specify Parser::WithinLatch.new(tag.to_s)
17
+ specify Latches::Within.new(tag.to_s)
18
18
  end
19
19
 
20
20
  def child_of(tag)
21
- specify Parser::ChildOfLatch.new(tag.to_s)
21
+ specify Latches::ChildOf.new(tag.to_s)
22
22
  end
23
23
 
24
24
  def with_attribute(name, value = nil)
25
- specify Parser::WithAttributeLatch.new(name.to_s, !!value ? value.to_s : nil)
25
+ specify Latches::WithAttributes.new({name.to_s => !!value ? value.to_s : nil })
26
+ end
27
+
28
+ def with_attributes(attrs)
29
+ if attrs.is_a? Array
30
+ attrs = Hash[attrs.map { |k| [k, nil]}]
31
+ elsif attrs.is_a? Hash
32
+ attrs = Hash[attrs.map{ |k, v| [k.to_s, v ? v.to_s : v]}]
33
+ else
34
+ raise ArgumentError.new("attributes should be a Hash or Array")
35
+ end
36
+ specify Latches::WithAttributes.new(attrs)
26
37
  end
27
38
 
28
39
  private
@@ -1,10 +1,8 @@
1
- require 'saxerator/dsl'
2
-
3
1
  module Saxerator
4
2
  class FullDocument
5
3
  include DSL
6
4
 
7
- def initialize(source, config = nil)
5
+ def initialize(source, config)
8
6
  @source = source
9
7
  @config = config
10
8
  @latches = []
@@ -1,8 +1,6 @@
1
- require 'nokogiri'
2
-
3
1
  module Saxerator
4
- module Parser
5
- class DocumentLatch < Nokogiri::XML::SAX::Document
2
+ module Latches
3
+ class AbstractLatch < Nokogiri::XML::SAX::Document
6
4
  def open
7
5
  @open = true
8
6
  end
@@ -1,6 +1,6 @@
1
1
  module Saxerator
2
- module Parser
3
- class AtDepthLatch < Nokogiri::XML::SAX::Document
2
+ module Latches
3
+ class AtDepth < Nokogiri::XML::SAX::Document
4
4
  def initialize(depth)
5
5
  @target_depth = depth
6
6
  @current_depth = -1
@@ -1,6 +1,6 @@
1
1
  module Saxerator
2
- module Parser
3
- class ChildOfLatch < Nokogiri::XML::SAX::Document
2
+ module Latches
3
+ class ChildOf < Nokogiri::XML::SAX::Document
4
4
  def initialize(name)
5
5
  @name = name
6
6
  @depths = []
@@ -1,8 +1,8 @@
1
- require 'saxerator/parser/document_latch'
1
+ require 'saxerator/latches/abstract_latch'
2
2
 
3
3
  module Saxerator
4
- module Parser
5
- class ForTagsLatch < DocumentLatch
4
+ module Latches
5
+ class ForTags < AbstractLatch
6
6
  def initialize(names)
7
7
  @names = names
8
8
  end
@@ -0,0 +1,24 @@
1
+ require 'saxerator/latches/abstract_latch'
2
+
3
+ module Saxerator
4
+ module Latches
5
+ class WithAttributes < AbstractLatch
6
+ def initialize(attrs)
7
+ @attrs = attrs
8
+ end
9
+
10
+ def start_element _, attributes
11
+ attributes = Hash[attributes]
12
+ if @attrs.all? { |k, v| attributes[k] && (v.nil? || attributes[k] == v) }
13
+ open
14
+ else
15
+ close
16
+ end
17
+ end
18
+
19
+ def end_element _
20
+ close
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,6 +1,6 @@
1
1
  module Saxerator
2
- module Parser
3
- class WithinLatch < Nokogiri::XML::SAX::Document
2
+ module Latches
3
+ class Within < Nokogiri::XML::SAX::Document
4
4
  def initialize(name)
5
5
  @name = name
6
6
  @depth_within_element = 0
@@ -1,5 +1,3 @@
1
- require 'nokogiri'
2
-
3
1
  module Saxerator
4
2
  module Parser
5
3
  class Accumulator < Nokogiri::XML::SAX::Document
@@ -7,10 +5,11 @@ module Saxerator
7
5
  @stack = []
8
6
  @config = config
9
7
  @block = block
8
+ @builder = Builder.to_class(@config.output_type)
10
9
  end
11
10
 
12
11
  def start_element(name, attrs = [])
13
- @stack.push XmlNode.new(@config, name, Hash[*attrs.flatten])
12
+ @stack.push @builder.new(@config, name, Hash[*attrs.flatten])
14
13
  end
15
14
 
16
15
  def end_element(_)
@@ -1,5 +1,3 @@
1
- require 'nokogiri'
2
-
3
1
  module Saxerator
4
2
  module Parser
5
3
  class LatchedAccumulator < Nokogiri::XML::SAX::Document
@@ -1,3 +1,3 @@
1
1
  module Saxerator
2
- VERSION = "0.5.0"
2
+ VERSION = "0.7.0"
3
3
  end
data/lib/saxerator.rb CHANGED
@@ -1,23 +1,35 @@
1
1
  require 'saxerator/version'
2
2
 
3
+ require 'nokogiri'
4
+
5
+ require 'saxerator/dsl'
3
6
  require 'saxerator/full_document'
4
7
  require 'saxerator/document_fragment'
5
- require 'saxerator/string_element'
6
- require 'saxerator/hash_element'
7
- require 'saxerator/xml_node'
8
+ require 'saxerator/configuration'
9
+
10
+ require 'saxerator/builder'
11
+ require 'saxerator/builder/string_element'
12
+ require 'saxerator/builder/hash_element'
13
+ require 'saxerator/builder/array_element'
14
+ require 'saxerator/builder/hash_builder'
15
+ require 'saxerator/builder/xml_builder'
8
16
 
9
17
  require 'saxerator/parser/accumulator'
10
- require 'saxerator/parser/for_tags_latch'
11
- require 'saxerator/parser/at_depth_latch'
12
- require 'saxerator/parser/within_latch'
13
18
  require 'saxerator/parser/latched_accumulator'
14
- require 'saxerator/parser/child_of_latch'
15
- require 'saxerator/parser/with_attribute_latch'
19
+
20
+ require 'saxerator/latches/for_tags'
21
+ require 'saxerator/latches/at_depth'
22
+ require 'saxerator/latches/within'
23
+ require 'saxerator/latches/child_of'
24
+ require 'saxerator/latches/with_attributes'
16
25
 
17
26
  module Saxerator
18
27
  extend self
19
28
 
20
29
  def parser(xml)
21
- Saxerator::FullDocument.new(xml)
30
+ config = Configuration.new
31
+ yield(config) if block_given?
32
+
33
+ Saxerator::FullDocument.new(xml, config)
22
34
  end
23
35
  end
@@ -9,9 +9,9 @@
9
9
  <id>1</id>
10
10
  <published>2012-01-01T16:17:00-06:00</published>
11
11
  <updated>2012-01-01T16:17:00-06:00</updated>
12
- <link type="text/html" href="https://example.com/blog/how-to-eat-an-airplane" rel="alternate"/>
12
+ <link href="https://example.com/blog/how-to-eat-an-airplane"/>
13
13
  <title>How to eat an airplane</title>
14
- <content type="html">&lt;p&gt;Airplanes are very large &#8212; this can present difficulty in digestion.&lt;/p&gt;</content>
14
+ <content type="html">&lt;p&gt;Airplanes are very large &#x2014; this can present difficulty in digestion.&lt;/p&gt;</content>
15
15
  <media:thumbnail url="http://www.gravatar.com/avatar/a9eb6ba22e482b71b266daadf9c9a080?s=80"/>
16
16
  <author>
17
17
  <name><![CDATA[Soul<utter]]></name>
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe "Saxerator (default) hash format" do
5
+ let(:xml) { fixture_file('nested_elements.xml') }
6
+ subject(:entry) { Saxerator.parser(xml).for_tag(:entry).first }
7
+
8
+ # string
9
+ specify { entry['title'].should == 'How to eat an airplane' }
10
+
11
+ # hash and cdata inside name
12
+ specify { entry['author'].should == {'name' => 'Soul<utter'} }
13
+
14
+ # array of hashes
15
+ specify { entry['contributor'].should == [{'name' => 'Jane Doe'}, {'name' => 'Leviticus Alabaster'}] }
16
+
17
+ # attributes on a hash
18
+ specify { entry['contributor'][0].attributes['type'].should == 'primary' }
19
+
20
+ # attributes on a string
21
+ specify { entry['content'].attributes['type'].should == 'html' }
22
+
23
+ # name on a hash
24
+ specify { entry.name.should == 'entry' }
25
+
26
+ # name on a string
27
+ specify { entry['title'].name.should == 'title' }
28
+
29
+ # name on an array
30
+ specify { entry['contributor'].name.should == 'contributor' }
31
+
32
+ # character entity decoding
33
+ specify { entry['content'].should == "<p>Airplanes are very large — this can present difficulty in digestion.</p>" }
34
+
35
+ # empty element
36
+ specify { entry['media:thumbnail'].should == {} }
37
+ end
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+ require 'spec_helper'
3
+
4
+ describe "Saxerator xml format" do
5
+ let(:xml) { fixture_file('nested_elements.xml') }
6
+ subject(:entry) do
7
+ Saxerator.parser(xml) do |config|
8
+ config.output_type = :xml
9
+ end.for_tag(:entry).first
10
+ end
11
+
12
+ it { should be_a(Nokogiri::XML::Node) }
13
+ it "looks like the original document" do
14
+ expected_xml = <<-eos
15
+ <?xml version="1.0"?>
16
+ <entry>
17
+ <id>1</id>
18
+ <published>2012-01-01T16:17:00-06:00</published>
19
+ <updated>2012-01-01T16:17:00-06:00</updated>
20
+ <link href="https://example.com/blog/how-to-eat-an-airplane"/>
21
+ <title>How to eat an airplane</title>
22
+ <content type="html">&lt;p&gt;Airplanes are very large &#x2014; this can present difficulty in digestion.&lt;/p&gt;</content>
23
+ <media:thumbnail url="http://www.gravatar.com/avatar/a9eb6ba22e482b71b266daadf9c9a080?s=80"/>
24
+ <author>
25
+ <name>Soul&lt;utter</name>
26
+ </author>
27
+ <contributor type="primary">
28
+ <name>Jane Doe</name>
29
+ </contributor>
30
+ <contributor>
31
+ <name>Leviticus Alabaster</name>
32
+ </contributor>
33
+ </entry>
34
+ eos
35
+ entry.to_xml.should == expected_xml
36
+ end
37
+ end
@@ -16,4 +16,8 @@ describe "Saxerator::DSL#for_tags" do
16
16
  it "should only select the specified tags" do
17
17
  parser.for_tags(%w(blurb1 blurb3)).inject([], :<<).should == ['one', 'three']
18
18
  end
19
+
20
+ it "raises an ArgumentError for a non-Array argument" do
21
+ lambda { parser.for_tags("asdf") }.should raise_error ArgumentError
22
+ end
19
23
  end
@@ -0,0 +1,32 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Saxerator::DSL#with_attributes" do
4
+ subject(:parser) { Saxerator.parser(xml) }
5
+
6
+ let(:xml) do
7
+ <<-eos
8
+ <book>
9
+ <name>How to eat an airplane</name>
10
+ <author>
11
+ <name type="primary" ridiculous="true">Leviticus Alabaster</name>
12
+ <name type="foreword" ridiculous="true">Eunice Diesel</name>
13
+ <name type="foreword">Jackson Frylock</name>
14
+ </author>
15
+ </book>
16
+ eos
17
+ end
18
+
19
+ it "matches tags with the exact specified attributes" do
20
+ parser.with_attributes(:type => :primary, :ridiculous => 'true').inject([], :<<).should == [
21
+ 'Leviticus Alabaster'
22
+ ]
23
+ end
24
+
25
+ it "matches tags which have the specified attributes" do
26
+ parser.with_attributes(%w(type ridiculous)).inject([], :<<).should == ['Leviticus Alabaster', 'Eunice Diesel']
27
+ end
28
+
29
+ it "raises ArgumentError if you pass something other than a Hash or Array" do
30
+ lambda { parser.with_attributes('asdf') }.should raise_error ArgumentError
31
+ end
32
+ end
@@ -3,10 +3,6 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe Saxerator do
6
- def fixture_file(name)
7
- File.new(File.join(File.dirname(__FILE__), '..', 'fixtures', name))
8
- end
9
-
10
6
  context "#parser" do
11
7
  subject(:parser) { Saxerator.parser(xml) }
12
8
 
@@ -41,35 +37,21 @@ describe Saxerator do
41
37
  end
42
38
  end
43
39
 
44
- context "block_variable format" do
45
- let(:xml) { fixture_file('nested_elements.xml') }
46
- subject(:entry) { Saxerator.parser(xml).for_tag(:entry).first }
47
-
48
- # string
49
- specify { entry['title'].should == 'How to eat an airplane' }
50
-
51
- # hash and cdata inside name
52
- specify { entry['author'].should == {'name' => 'Soul<utter'} }
53
-
54
- # array of hashes
55
- specify { entry['contributor'].should == [{'name' => 'Jane Doe'}, {'name' => 'Leviticus Alabaster'}] }
56
-
57
- # attributes on a hash
58
- specify { entry['contributor'][0].attributes['type'].should == 'primary' }
59
-
60
- # attributes on a string
61
- specify { entry['content'].attributes['type'].should == 'html' }
62
-
63
- # name on a hash
64
- specify { entry.name.should == 'entry' }
40
+ context "output_type configuration" do
41
+ subject(:parser) do
42
+ Saxerator.parser(xml) { |config| config.output_type = output_type }
43
+ end
65
44
 
66
- # name on a string
67
- specify { entry['title'].name.should == 'title' }
45
+ let(:xml) { "<foo><bar>baz</bar></foo>" }
68
46
 
69
- # character entity decoding
70
- specify { entry['content'].should == "<p>Airplanes are very large — this can present difficulty in digestion.</p>"}
47
+ context "with config.output_type = :hash" do
48
+ let(:output_type) { :hash }
49
+ specify { parser.all.should == {'bar' => 'baz'} }
50
+ end
71
51
 
72
- # empty element
73
- specify { entry['media:thumbnail'].should == {} }
52
+ context "with an invalid config.output_type" do
53
+ let(:output_type) { 'lmao' }
54
+ specify { lambda { parser }.should raise_error(ArgumentError) }
55
+ end
74
56
  end
75
57
  end
data/spec/spec_helper.rb CHANGED
@@ -5,4 +5,10 @@ if ENV['COVERAGE']
5
5
  end
6
6
  end
7
7
 
8
+ Dir['./spec/support/**/*.rb'].each { |f| require f }
9
+
10
+ RSpec.configure do |config|
11
+ config.include FixtureFile
12
+ end
13
+
8
14
  require 'saxerator'
@@ -0,0 +1,5 @@
1
+ module FixtureFile
2
+ def fixture_file(name)
3
+ File.new(File.join(File.dirname(__FILE__), '..', 'fixtures', name))
4
+ end
5
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: saxerator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.7.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-05 00:00:00.000000000 Z
12
+ date: 2012-09-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: nokogiri
@@ -59,33 +59,41 @@ files:
59
59
  - Rakefile
60
60
  - .gitignore
61
61
  - .travis.yml
62
+ - lib/saxerator/builder/array_element.rb
63
+ - lib/saxerator/builder/hash_builder.rb
64
+ - lib/saxerator/builder/hash_element.rb
65
+ - lib/saxerator/builder/string_element.rb
66
+ - lib/saxerator/builder/xml_builder.rb
67
+ - lib/saxerator/builder.rb
68
+ - lib/saxerator/configuration.rb
62
69
  - lib/saxerator/document_fragment.rb
63
70
  - lib/saxerator/dsl.rb
64
71
  - lib/saxerator/full_document.rb
65
- - lib/saxerator/hash_element.rb
72
+ - lib/saxerator/latches/abstract_latch.rb
73
+ - lib/saxerator/latches/at_depth.rb
74
+ - lib/saxerator/latches/child_of.rb
75
+ - lib/saxerator/latches/for_tags.rb
76
+ - lib/saxerator/latches/with_attributes.rb
77
+ - lib/saxerator/latches/within.rb
66
78
  - lib/saxerator/parser/accumulator.rb
67
- - lib/saxerator/parser/at_depth_latch.rb
68
- - lib/saxerator/parser/child_of_latch.rb
69
- - lib/saxerator/parser/document_latch.rb
70
- - lib/saxerator/parser/for_tags_latch.rb
71
79
  - lib/saxerator/parser/latched_accumulator.rb
72
- - lib/saxerator/parser/with_attribute_latch.rb
73
- - lib/saxerator/parser/within_latch.rb
74
- - lib/saxerator/string_element.rb
75
80
  - lib/saxerator/version.rb
76
- - lib/saxerator/xml_node.rb
77
81
  - lib/saxerator.rb
78
82
  - spec/fixtures/flat_blurbs.xml
79
83
  - spec/fixtures/nested_elements.xml
84
+ - spec/lib/builder/hash_builder_spec.rb
85
+ - spec/lib/builder/xml_builder_spec.rb
80
86
  - spec/lib/dsl/all_spec.rb
81
87
  - spec/lib/dsl/at_depth_spec.rb
82
88
  - spec/lib/dsl/child_of_spec.rb
83
89
  - spec/lib/dsl/for_tag_spec.rb
84
90
  - spec/lib/dsl/for_tags_spec.rb
85
91
  - spec/lib/dsl/with_attribute_spec.rb
92
+ - spec/lib/dsl/with_attributes_spec.rb
86
93
  - spec/lib/dsl/within_spec.rb
87
94
  - spec/lib/saxerator_spec.rb
88
95
  - spec/spec_helper.rb
96
+ - spec/support/fixture_file.rb
89
97
  - benchmark/benchmark.rb
90
98
  - benchmark/generate_sample_file.rb
91
99
  homepage: https://github.com/soulcutter/saxerator
@@ -116,12 +124,16 @@ summary: A SAX-based XML-to-hash parser for parsing large files into manageable
116
124
  test_files:
117
125
  - spec/fixtures/flat_blurbs.xml
118
126
  - spec/fixtures/nested_elements.xml
127
+ - spec/lib/builder/hash_builder_spec.rb
128
+ - spec/lib/builder/xml_builder_spec.rb
119
129
  - spec/lib/dsl/all_spec.rb
120
130
  - spec/lib/dsl/at_depth_spec.rb
121
131
  - spec/lib/dsl/child_of_spec.rb
122
132
  - spec/lib/dsl/for_tag_spec.rb
123
133
  - spec/lib/dsl/for_tags_spec.rb
124
134
  - spec/lib/dsl/with_attribute_spec.rb
135
+ - spec/lib/dsl/with_attributes_spec.rb
125
136
  - spec/lib/dsl/within_spec.rb
126
137
  - spec/lib/saxerator_spec.rb
127
138
  - spec/spec_helper.rb
139
+ - spec/support/fixture_file.rb
@@ -1,11 +0,0 @@
1
- module Saxerator
2
- class HashElement < Hash
3
- attr_accessor :attributes
4
- attr_accessor :name
5
-
6
- def initialize(name, attributes)
7
- self.name = name
8
- self.attributes = attributes
9
- end
10
- end
11
- end
@@ -1,25 +0,0 @@
1
- require 'saxerator/parser/document_latch'
2
-
3
- module Saxerator
4
- module Parser
5
- class WithAttributeLatch < DocumentLatch
6
- def initialize(name, value)
7
- @attr_name = name
8
- @attr_value = value
9
- end
10
-
11
- def start_element _, attributes
12
- attributes = Hash[attributes]
13
- if attributes[@attr_name] && (@attr_value.nil? || attributes[@attr_name] == @attr_value)
14
- open
15
- else
16
- close
17
- end
18
- end
19
-
20
- def end_element _
21
- close
22
- end
23
- end
24
- end
25
- end
@@ -1,12 +0,0 @@
1
- module Saxerator
2
- class StringElement < String
3
- attr_accessor :attributes
4
- attr_accessor :name
5
-
6
- def initialize(str, name, attributes)
7
- self.name = name
8
- self.attributes = attributes
9
- super(str)
10
- end
11
- end
12
- end
@@ -1,46 +0,0 @@
1
- module Saxerator
2
- class XmlNode
3
- attr_reader :name
4
-
5
- def initialize(config, name, attributes)
6
- @config = config
7
- @name = name
8
- @attributes = attributes
9
- @children = []
10
- @text = false
11
- end
12
-
13
- def add_node(node)
14
- @text = true if node.is_a? String
15
- @children << node
16
- end
17
-
18
- def to_s
19
- StringElement.new(@children.join, @name, @attributes)
20
- end
21
-
22
- def to_hash
23
- hash = HashElement.new(@name, @attributes)
24
-
25
- @children.each do |child|
26
- name = child.name
27
- element = child.block_variable
28
-
29
- if hash[name]
30
- if !hash[name].is_a?(Array)
31
- hash[name] = [hash[name]]
32
- end
33
- hash[name] << element
34
- else
35
- hash[name] = element
36
- end
37
- end
38
-
39
- hash
40
- end
41
-
42
- def block_variable
43
- @text ? to_s : to_hash
44
- end
45
- end
46
- end