xmlcodec 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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: