xmlcodec 0.0.3 → 0.0.4

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.
data/Rakefile CHANGED
@@ -1,5 +1,5 @@
1
1
  PKG_NAME = 'xmlcodec'
2
- PKG_VERSION = '0.0.3'
2
+ PKG_VERSION = '0.0.4'
3
3
 
4
4
  require 'rake'
5
5
  require 'rake/testtask'
data/lib/XMLElement.rb CHANGED
@@ -491,6 +491,11 @@ module XMLCodec
491
491
  if not already_partial_export_ended?
492
492
  @already_partial_export_ended = true
493
493
 
494
+ if not already_partial_exported?
495
+ raise "<#{self} Trying to end the export of an element that hasn't"+
496
+ " been started yet"
497
+ end
498
+
494
499
  each_subelement do |e|
495
500
  e.end_partial_export(file)
496
501
  end
@@ -5,13 +5,13 @@ module XMLCodec
5
5
  # This class is used internally by the parser to store the information about
6
6
  # each of the elements that gets created.
7
7
  class XMLSOParserElement
8
- attr_reader :elclass, :consumed, :id
8
+ attr_reader :elclass, :consumed, :id, :depth
9
9
 
10
10
  # Create a new instance with the element name, a hash of atributes, it's
11
11
  # import/export class, the parent element and it's id
12
12
  # The id is used to fill in element_id and parent_id in XMLElement so that
13
13
  # the parser's user can know what is the tree structure between objects.
14
- def initialize(name, attrs, elclass, parent, id)
14
+ def initialize(name, attrs, elclass, parent, id, depth)
15
15
  @attrs = attrs
16
16
  @elclass = elclass
17
17
  @children = Hash.new([])
@@ -21,6 +21,7 @@ module XMLCodec
21
21
  @parent = parent
22
22
  @id = id
23
23
  @name = name
24
+ @depth = depth
24
25
  end
25
26
 
26
27
  # Add a child element to the object
@@ -65,7 +66,7 @@ module XMLCodec
65
66
  @listener = listener
66
67
  @children = Hash.new([])
67
68
  @currel = 0
68
- @elements = [XMLSOParserElement.new(nil, nil, nil, nil, nil)]
69
+ @elements = [XMLSOParserElement.new(nil, nil, nil, nil, nil, 0)]
69
70
  @id = 0
70
71
  @top_element = nil
71
72
  end
@@ -102,7 +103,8 @@ module XMLCodec
102
103
 
103
104
  def tag_start(name, attrs) #:nodoc:
104
105
  @elements << XMLSOParserElement.new(name, attrs, get_elclass(name),
105
- curr_element, next_id)
106
+ curr_element, next_id,
107
+ curr_element.depth+1)
106
108
  @currel += 1
107
109
  end
108
110
 
@@ -91,7 +91,9 @@ module XMLUtils
91
91
 
92
92
  def tag_end(name)
93
93
  @contents << "</"+name+">"
94
- element(name)
94
+ if @listener.respond_to? 'el_'+name
95
+ @listener.send('el_'+name, @elements[-1])
96
+ end
95
97
  @elements.pop()
96
98
  end
97
99
 
@@ -99,12 +101,6 @@ module XMLUtils
99
101
  @contents.text_from(@elements[-1].elstart)
100
102
  end
101
103
 
102
- def element(name)
103
- if @listener
104
- @listener.element(@elements[-1])
105
- end
106
- end
107
-
108
104
  def consume
109
105
  @contents.erase_from(@elements[-1].elstart)
110
106
  end
data/lib/XMLUtils.rb CHANGED
@@ -1,4 +1,5 @@
1
- require "rexml/document"
1
+ require 'rexml/document'
2
+ require 'stringio'
2
3
 
3
4
  # This module holds generic XML utilities. The module's methods are simple
4
5
  # XML utilities. The module also contains XMLStreamParser, a Generic XML Stream
@@ -16,7 +17,7 @@ module XMLUtils
16
17
  def self.count_elements(path, filename)
17
18
  doc = getdoc(filename)
18
19
  i = 0
19
- XPath.each(doc, path) {|element| i+=1}
20
+ REXML::XPath.each(doc, path) {|element| i+=1}
20
21
  return i
21
22
  end
22
23
 
@@ -55,4 +56,51 @@ module XMLUtils
55
56
  t.write_with_substitution(str, string)
56
57
  str
57
58
  end
59
+
60
+ # Gets the xpath inside a given document that can either be a string or a
61
+ # REXML::Document
62
+ #
63
+ # opts can have:
64
+ # :multiple: fetch all the occurences of the xpath
65
+ # :with_attrs: include the attribute contents in the result
66
+ # :recursive: recursively include all the subelements of the matches
67
+ def self.get_xpath(path, doc, opts={})
68
+ if doc.is_a? REXML::Document
69
+ doc = doc
70
+ else
71
+ doc = REXML::Document.new(doc)
72
+ end
73
+
74
+ if opts[:multiple]
75
+ strs = []
76
+ REXML::XPath.each(doc.root, path) do |e|
77
+ t = get_rexml_content(e, opts)
78
+ strs << t if t != ''
79
+ end
80
+ return strs.join(' ')
81
+ else
82
+ return get_rexml_content(REXML::XPath.first(doc, path), opts)
83
+ end
84
+ end
85
+
86
+ def self.get_rexml_content(element, opts={})
87
+ return '' if not element
88
+ strs = []
89
+ if element.respond_to?('value')
90
+ return element.value || ''
91
+ else
92
+ if opts[:with_attrs]
93
+ element.attributes.each {|name, value| strs << value if value != ''}
94
+ end
95
+ if not opts[:recursive]
96
+ element.texts.each {|t| strs << t if t != ''}
97
+ else
98
+ element.to_a.each do |e|
99
+ t = get_rexml_content(e, opts)
100
+ strs << t if t != ''
101
+ end
102
+ end
103
+ end
104
+ strs.join(' ')
105
+ end
58
106
  end
@@ -142,4 +142,31 @@ class TestPartialExport < Test::Unit::TestCase
142
142
  compare_xpath(value1, filename, "/subels/abc[1]")
143
143
  compare_xpath(value2, filename, "/subels/abc[2]")
144
144
  end
145
+
146
+ def test_recursive
147
+ filename = 'test_partial_export_recursive.xml'
148
+ file = File.open(filename, "w")
149
+
150
+ value = 'somevalue'
151
+
152
+ rec1 = Recursive.new
153
+ rec1.start_partial_export(file)
154
+
155
+ rec2 = Recursive.new
156
+ rec1.recursive << rec2
157
+ rec2.start_partial_export(file)
158
+
159
+ rec3 = Recursive.new
160
+ rec2.recursive << rec3
161
+ rec3.start_partial_export(file)
162
+
163
+ sel = SimpleElement.new(value)
164
+ sel.start_partial_export(file)
165
+ rec3.abc = sel
166
+
167
+ rec1.end_partial_export(file)
168
+
169
+ file.close
170
+ validate_well_formed(filename)
171
+ end
145
172
  end
@@ -7,19 +7,19 @@ include XMLCodec
7
7
  class MyStreamListener
8
8
  attr_reader :abc, :subels, :mult, :subel
9
9
  def el_abc(el)
10
- @abc = el.get_object
10
+ @abc = el
11
11
  end
12
12
 
13
13
  def el_subels(el)
14
- @subels = el.get_object
14
+ @subels = el
15
15
  end
16
16
 
17
17
  def el_mult(el)
18
- @mult = el.get_object
18
+ @mult = el
19
19
  end
20
20
 
21
21
  def el_subel(el)
22
- @subel = el.get_object
22
+ @subel = el
23
23
  end
24
24
  end
25
25
 
@@ -28,7 +28,7 @@ class MyConsumingStreamListener
28
28
 
29
29
  def el_abc(el)
30
30
  el.consume
31
- @abc = el.get_object
31
+ @abc = el
32
32
  end
33
33
  end
34
34
 
@@ -46,7 +46,7 @@ class TestXMLStreamObjectParser < Test::Unit::TestCase
46
46
  listener = MyStreamListener.new
47
47
  parser = XMLStreamObjectParser.new(listener)
48
48
  parser.parse(file)
49
- el = listener.abc
49
+ el = listener.abc.get_object
50
50
  assert_equal el.value, value
51
51
  end
52
52
 
@@ -59,7 +59,7 @@ class TestXMLStreamObjectParser < Test::Unit::TestCase
59
59
  parser = XMLStreamObjectParser.new(listener)
60
60
  parser.parse(file)
61
61
 
62
- el = listener.abc
62
+ el = listener.abc.get_object
63
63
  assert_equal el.value, value
64
64
 
65
65
  subel = parser.top_element
@@ -67,10 +67,6 @@ class TestXMLStreamObjectParser < Test::Unit::TestCase
67
67
  assert_equal attrvalue, subel.someattr
68
68
  end
69
69
 
70
- def test_multiple_names
71
-
72
- end
73
-
74
70
  def test_mult
75
71
  value = 'somevalue'
76
72
  file = '<mult><abc>'+value+'</abc></mult>'
@@ -79,7 +75,7 @@ class TestXMLStreamObjectParser < Test::Unit::TestCase
79
75
  parser = XMLStreamObjectParser.new(listener)
80
76
  parser.parse(file)
81
77
 
82
- el = listener.abc
78
+ el = listener.abc.get_object
83
79
  assert_equal el.value, value
84
80
  assert_equal el, parser.top_element.abc[0]
85
81
  end
@@ -92,7 +88,7 @@ class TestXMLStreamObjectParser < Test::Unit::TestCase
92
88
  parser = XMLStreamObjectParser.new(listener)
93
89
  parser.parse(file)
94
90
 
95
- el = listener.abc
91
+ el = listener.abc.get_object
96
92
  assert_equal el.value, value
97
93
  assert_equal el, parser.top_element.subelements[0]
98
94
  end
@@ -105,7 +101,7 @@ class TestXMLStreamObjectParser < Test::Unit::TestCase
105
101
  parser = XMLStreamObjectParser.new(listener)
106
102
  parser.parse(file)
107
103
 
108
- el = listener.abc
104
+ el = listener.abc.get_object
109
105
  assert_equal el.value, value
110
106
  assert_nil parser.top_element.abc
111
107
  end
@@ -119,7 +115,7 @@ class TestXMLStreamObjectParser < Test::Unit::TestCase
119
115
  parser = XMLStreamObjectParser.new(listener)
120
116
  parser.parse(file)
121
117
 
122
- el = listener.subels
118
+ el = listener.subels.get_object
123
119
  assert_equal 2, el.subelements.size
124
120
  [value1, value2].each_with_index do |value, index|
125
121
  assert_kind_of SimpleElementMultName, el.subelements[index]
@@ -136,7 +132,7 @@ class TestXMLStreamObjectParser < Test::Unit::TestCase
136
132
  parser = XMLStreamObjectParser.new(listener)
137
133
  parser.parse(file)
138
134
 
139
- el = listener.mult
135
+ el = listener.mult.get_object
140
136
  assert_equal 2, el.abc2.size
141
137
  [value1, value2].each_with_index do |value, index|
142
138
  assert_kind_of SimpleElementMultName, el.abc2[index]
@@ -152,9 +148,23 @@ class TestXMLStreamObjectParser < Test::Unit::TestCase
152
148
  parser = XMLStreamObjectParser.new(listener)
153
149
  parser.parse(file)
154
150
 
155
- el = listener.subel
151
+ el = listener.subel.get_object
156
152
  assert_not_nil el.abc2
157
153
  assert_kind_of SimpleElementMultName, el.abc2
158
154
  assert_equal value, el.abc2.value
159
155
  end
156
+
157
+ def test_depth
158
+ value = 'somevalue'
159
+ file = '<subel><abc>'+value+'</abc></subel>'
160
+
161
+ listener = MyStreamListener.new
162
+ parser = XMLStreamObjectParser.new(listener)
163
+ parser.parse(file)
164
+
165
+ el1 = listener.subel
166
+ el2 = listener.abc
167
+
168
+ assert el1.depth < el2.depth
169
+ end
160
170
  end
@@ -4,44 +4,44 @@ $-w = true
4
4
  require 'test/unit'
5
5
  require 'XMLStreamParser'
6
6
 
7
- class MyStreamListener
8
- attr_reader :def_id, :def_parent_id
9
- attr_reader :abc_id, :abc_parent_id
10
- def element(el)
11
- case el.name
12
- when "def"
13
- @def_id, = el.element_id
14
- @def_parent_id = el.parent_id
15
- el.consume
16
- when "abc"
17
- @abc_id, = el.element_id
18
- @abc_parent_id = el.parent_id
19
- el.consume
20
- end
21
- end
7
+ class MyXMLStreamListener
8
+ attr_reader :def_id, :def_parent_id
9
+ attr_reader :abc_id, :abc_parent_id
10
+
11
+ def el_def(el)
12
+ @def_id, = el.element_id
13
+ @def_parent_id = el.parent_id
14
+ el.consume
15
+ end
16
+
17
+ def el_abc(el)
18
+ @abc_id, = el.element_id
19
+ @abc_parent_id = el.parent_id
20
+ el.consume
21
+ end
22
22
  end
23
23
 
24
24
  class TestXMLStreamParser < Test::Unit::TestCase
25
- def initialize(*args)
26
- super(*args)
27
- @doc = "<abc attr1='1' attr2='2'>abc<xpto attr1='a'></xpto><def><x></x></def></abc>"
28
- @doc_no_def = "<abc attr1='1' attr2='2'>abc<xpto attr1='a'></xpto></abc>"
29
- end
25
+ def initialize(*args)
26
+ super(*args)
27
+ @doc = "<abc attr1='1' attr2='2'>abc<xpto attr1='a'></xpto><def><x></x></def></abc>"
28
+ @doc_no_def = "<abc attr1='1' attr2='2'>abc<xpto attr1='a'></xpto></abc>"
29
+ end
30
30
 
31
- def test_total_parse
32
- parser = XMLUtils::XMLStreamParser.new
33
- parser.parse(@doc)
34
- assert_equal(@doc, parser.content)
35
- end
36
-
37
- def test_consumed_parse
38
- listener = MyStreamListener.new
39
- parser = XMLUtils::XMLStreamParser.new(listener)
40
- parser.parse(@doc)
41
- assert_equal(@doc_no_def, parser.content)
42
- assert_equal(listener.abc_id, listener.def_parent_id)
43
- assert_equal(0, listener.abc_parent_id)
44
- assert_equal(1, listener.abc_id)
45
- assert(listener.def_id > listener.def_parent_id)
46
- end
31
+ def test_total_parse
32
+ parser = XMLUtils::XMLStreamParser.new
33
+ parser.parse(@doc)
34
+ assert_equal(@doc, parser.content)
35
+ end
36
+
37
+ def test_consumed_parse
38
+ listener = MyXMLStreamListener.new
39
+ parser = XMLUtils::XMLStreamParser.new(listener)
40
+ parser.parse(@doc)
41
+ assert_equal(@doc_no_def, parser.content)
42
+ assert_equal(listener.abc_id, listener.def_parent_id)
43
+ assert_equal(0, listener.abc_parent_id)
44
+ assert_equal(1, listener.abc_id)
45
+ assert(listener.def_id > listener.def_parent_id)
46
+ end
47
47
  end
data/test/TestXMLUtils.rb CHANGED
@@ -4,14 +4,47 @@ require 'test/unit'
4
4
  require 'XMLUtils'
5
5
 
6
6
  class TestXMLUtils < Test::Unit::TestCase
7
- def test_create_open_tag
8
- tag = XMLUtils::create_open_tag("name", {"arg1" => "val1", "arg2" => "val2"})
9
- assert_equal("<name arg1='val1' arg2='val2'>", tag)
10
- end
11
-
12
- def test_escape_xml
13
- assert_equal '&lt; abc', XMLUtils::escape_xml('< abc')
14
- assert_equal '&gt; abc', XMLUtils::escape_xml('> abc')
15
- assert_equal '&amp; abc', XMLUtils::escape_xml('& abc')
16
- end
7
+ def test_create_open_tag
8
+ tag = XMLUtils::create_open_tag("name", {"arg1" => "val1", "arg2" => "val2"})
9
+ assert_equal("<name arg1='val1' arg2='val2'>", tag)
10
+ end
11
+
12
+ def test_escape_xml
13
+ assert_equal '&lt; abc', XMLUtils::escape_xml('< abc')
14
+ assert_equal '&gt; abc', XMLUtils::escape_xml('> abc')
15
+ assert_equal '&amp; abc', XMLUtils::escape_xml('& abc')
16
+ end
17
+
18
+ def test_get_xpath
19
+ opts = {}
20
+ assert_xpath_equal('abc', '//xpto', '<xpto>abc<xpto>')
21
+
22
+ assert_xpath_equal('abc', '//xpto', '<xpto>abc<xpto2>foo</xpto2><xpto>')
23
+
24
+ opts[:with_attrs] = true
25
+ opts[:recursive] = false
26
+ opts[:multiple] = false
27
+ assert_xpath_equal('attr1 abc', '//xpto', '<xpto attr1="attr1">abc<xpto2>foo</xpto2><xpto>', opts)
28
+
29
+ opts[:with_attrs] = false
30
+ opts[:recursive] = true
31
+ opts[:multiple] = false
32
+ assert_xpath_equal('abc foo', '//xpto', '<xpto>abc<xpto2 attr1="attr1">foo</xpto2><xpto>', opts)
33
+
34
+ opts[:with_attrs] = true
35
+ opts[:recursive] = true
36
+ opts[:multiple] = false
37
+ assert_xpath_equal('abc attr1 foo', '//xpto', '<xpto>abc<xpto2 attr1="attr1">foo</xpto2><xpto>', opts)
38
+
39
+ opts[:with_attrs] = false
40
+ opts[:recursive] = false
41
+ opts[:multiple] = true
42
+ assert_xpath_equal('abc foo', '//xpto', '<xpto>abc<xpto attr1="attr1">foo</xpto><xpto>', opts)
43
+ end
44
+
45
+ def assert_xpath_equal(result, path, xml, opts={})
46
+ assert_equal result, XMLUtils::get_xpath(path, xml, opts)
47
+ assert_equal result, XMLUtils::get_xpath(path, StringIO.new(xml), opts)
48
+ assert_equal result, XMLUtils::get_xpath(path, REXML::Document.new(xml), opts)
49
+ end
17
50
  end
@@ -45,3 +45,9 @@ class SubelMultElement < XMLElement
45
45
  xmlsubel_mult :abc
46
46
  xmlsubel_mult :abc2
47
47
  end
48
+
49
+ class Recursive < XMLElement
50
+ elname 'recursive'
51
+ xmlsubel :abc
52
+ xmlsubel_mult :recursive
53
+ end
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.8.11
2
+ rubygems_version: 0.9.0
3
3
  specification_version: 1
4
4
  name: xmlcodec
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.0.3
7
- date: 2006-05-29 00:00:00 +01:00
6
+ version: 0.0.4
7
+ date: 2006-07-06 00:00:00 +01:00
8
8
  summary: Generic Importer/Exporter of XML formats
9
9
  require_paths:
10
10
  - lib
@@ -25,6 +25,7 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
25
25
  platform: ruby
26
26
  signing_key:
27
27
  cert_chain:
28
+ post_install_message:
28
29
  authors:
29
30
  - "Pedro C\xC3\xB4rte-Real"
30
31
  files: