duxml 0.7.2 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a443f0b41070e85e05a9042711af460f1a9de0ce
4
- data.tar.gz: c25d6801574a1730e3a38a5ccab2ed91b482d37b
3
+ metadata.gz: 5cfc64bf0a2a0fc7d5dfa7eddf824a91de78019e
4
+ data.tar.gz: 68539178080588cf391bd98619dd994f2e55fd6a
5
5
  SHA512:
6
- metadata.gz: 2804f997a7fa48f9bd6c24ddef5e8b84df058b4bfbc1f6a41cbda340646378ef0d94a95a32b89cc1160819bb2d9bf37926c8196e2e8f5d9d70950a5baa973f3b
7
- data.tar.gz: d2cac9f2b2c16c07b754f98224eea4da660857a73345215bed10824818cd837de15ce2fe98bb06a2100eb69171537fd270ae27dd6199710c1e740c88fd3d2711
6
+ metadata.gz: f176dc33c32a6293ff8d3df5e04ac7e48b9fd6edf275b1fe0260c56b18e5baa24366f9335bad203367d1f2aee5413be9dd17e92be4f4bccb1190f92428ac8bbc
7
+ data.tar.gz: cc453d524c27917c4ad689023e4622090edc17c3a08b4ecb42383a93c7c0516422fcb958ad29333e04d859a48efe88939c26db1125491fc47aaba925cf6f7ec0
data/bin/validate_xml CHANGED
@@ -16,4 +16,16 @@ puts "loaded grammar file: #{DITA_GRAMMAR_FILE}"
16
16
  validate
17
17
  puts "validation complete"
18
18
  log log_file
19
- puts "logged errors to #{log_file}"
19
+ puts "logged errors to #{log_file}"
20
+
21
+
22
+ if conditions
23
+
24
+ end
25
+
26
+
27
+ def conditions
28
+ asdf and b and c
29
+ end
30
+
31
+ File
@@ -25,7 +25,7 @@ module Duxml
25
25
  # in Ruby mode, args are some combination of new attributes/values and/or child nodes (text or XML) with which to initialize this node
26
26
  #
27
27
  # @param name [String] name of element, in both Ruby and file modes
28
- # @param _line_content [Fixnum, Array, Hash] line number of element file mode; if Array, new child nodes; if Hash, attributes; can be nil
28
+ # @param _line_or_content [Fixnum, Array, Hash] line number of element file mode; if Array, new child nodes; if Hash, attributes; can be nil
29
29
  # @param _col_or_children [Fixnum, Array] column position in file mode; if Array, new child nodes; can be nil
30
30
  def initialize(name, _line_or_content=nil, _col_or_children=nil)
31
31
  super name
@@ -51,18 +51,31 @@ module Duxml
51
51
  # @see Ox::Element#<<
52
52
  # this override reports changes to history; NewText for Strings, Add for elements
53
53
  #
54
- # @param obj [Element] element or string to add to this Element
54
+ # @param obj [Element, Array] element or string to add to this Element; can insert arrays which are always inserted in order
55
55
  # @return [Element] self
56
56
  def <<(obj)
57
+ add(obj)
58
+ end
59
+
60
+ # @see #<<
61
+ # this version of the method allows insertions between existing elements
62
+ #
63
+ # @param obj [Element, Array] element or string to add to this Element; can insert arrays which are always inserted in order
64
+ # @param index [Fixnum] index at which to insert new node; inserts at end of element by default; when inserting arrays, index is incremented for each item to avoid reversing array order
65
+ # @return [Element] self
66
+ def add(obj, index=-1)
57
67
  case
58
68
  when obj.is_a?(Array), obj.is_a?(NodeSet)
59
- obj.each do |e| self << e end
69
+ obj.each_with_index do |e, i|
70
+ add(e, index == -1 ? index : index+i)
71
+ end
60
72
  when obj.is_a?(String)
61
73
  type = :NewText
62
- super(obj)
74
+ nodes.insert(index, obj)
75
+ report(type, nodes.size-1)
63
76
  else
64
77
  type = :Add
65
- super(obj)
78
+ nodes.insert(index, obj)
66
79
  if nodes.last.count_observers < 1 && @observer_peers
67
80
  nodes.last.add_observer(@observer_peers.first.first)
68
81
  end
@@ -71,10 +84,21 @@ module Duxml
71
84
  self
72
85
  end
73
86
 
74
- # @param attr_sym [String, Symbol] name of attribute
75
- # @param val [String]
87
+ # @param index_or_attr [String, Symbol, Fixnum] string or symbol of attribute or index of child node
88
+ # @return [Element, String] string if attribute value or text node; Element if XML node
89
+ def [](index_or_attr)
90
+ index_or_attr.is_a?(Fixnum) ? nodes[index_or_attr] : super(index_or_attr)
91
+ end
92
+
93
+ # @param attr_sym [String, Symbol, Fixnum] name of attribute or index of child to replace
94
+ # @param val [String] new attribute value or replacement child node
76
95
  # @return [Element] self
77
96
  def []=(attr_sym, val)
97
+ if attr_sym.is_a?(Fixnum)
98
+ remove nodes[attr_sym]
99
+ add(val, attr_sym)
100
+ return self
101
+ end
78
102
  attr = attr_sym.to_s
79
103
  raise "argument to [] must be a Symbol or a String." unless attr.is_a?(Symbol) or attr.is_a?(String)
80
104
  args = [attr]
@@ -1,153 +1,153 @@
1
- # Copyright (c) 2016 Freescale Semiconductor Inc.
2
-
3
- require File.expand_path(File.dirname(__FILE__) + '/../ruby_ext/string')
4
-
5
-
6
- module Duxml
7
- module LazyOx
8
- # welcome to Lazy-Ox - where any method that doesn't exist, you can create on the fly and assign its methods to
9
- # a corresponding Duxml::Element. see Regexp.nmtoken and String#nmtokenize and String#constantize to see how a given symbol
10
- # can be converted into XML element names and vice versa. it can also use Class names as method calls to return children by type
11
- #
12
- # this method uses Ox::Element's :method_missing but adds an additional rescue block that:
13
- # matches namespaced Ruby module to this Element's name and extends this node with module's methods
14
- # then method matching symbol is called again with given arguments, yielding result to block if given, returning result if not
15
- # e.g.
16
- # module Duxml
17
- # module Throwable
18
- # def throw
19
- # puts 'throwing!!'
20
- # end
21
- # end
22
- # end
23
- #
24
- # Element.new('throwable').throw => 'throwing!!'
25
- #
26
- # if symbol name matches a class then method yields to block or returns as array child nodes that matches class
27
- # you can further refine search results by adding the symbol of the child instance variable, including name, by which to filter
28
- # if block given, returns first child for which block evaluates to true
29
- #
30
- # e.g.
31
- # class Child; end
32
- #
33
- # n = Element.new('node')
34
- # n << 'text'
35
- # n << Element.new('child')
36
- # n << Element.new('child')
37
- # n.Element # returns Array of Element nodes
38
- # => [#<Duxml::Element:0x0002 @value="child" ...>,
39
- # #<Duxml::Element:0x0003 @value="child" ...>]
40
- #
41
- # n.Element.each do |child| child << 'some text' end # adding some text
42
- # => ['text',
43
- # #<Duxml::Element:0x0002 @value="child" ... @nodes=['some text']>,
44
- # #<Duxml::Element 0x0003 @value="child" ... @nodes=['some text']>]
45
- #
46
- # n.Element do |child| child.nodes.first == 'some text' end # returns all children for which block is true
47
- # => [#<Duxml::Element:0x0002 @value="child" ... @nodes=['some text']>]
48
- #
49
- # %w(bar mar).each_with_index do |x, i| next if i.zero?; n.Child[:foo] = x end # adding some attributes
50
- # => ['text',
51
- # #<Duxml::Element:0x0002 @value="child" @attributes={foo: 'bar'} ...>,
52
- # #<Duxml::Element:0x0003 @value="child" @attributes={foo: 'mar'} ...>]
53
- #
54
- # n.Element(:foo) # returns array of Child nodes with attribute :foo
55
- # => [#<Duxml::Element:0x0002 @value="child" @attributes={foo: 'bar'} ...>,
56
- # #<Duxml::Element:0x0003 @value="child" @attributes={foo: 'mar'} ...>]
57
- #
58
- # n.Element(foo: 'bar') # returns array of Child nodes with attribute :foo equal to 'bar'
59
- # => [#<Duxml::Element:0xfff @value="child" @attributes={foo: 'bar'} ...>]
60
- #
61
- #
62
- # if element name has no matching Class or Module in namespace,
63
- # if symbol is lower case, it is made into a method, given &block as definition, then called with *args
64
- # e.g. n.change_color('blue') do |new_color| => #<Duxml::Element:0xfff @value="node" @attributes={color: 'blue'} @nodes=[]>
65
- # @color = new_color
66
- # self
67
- # end
68
- # n.color => 'blue'
69
- # n.change_color('mauve').color => 'mauve'
70
- #
71
- # @param sym [Symbol] method, class or module
72
- # @param *args [*several_variants] either arguments to method or initializing values for instance of given class
73
- # @param &block [block] if yielding result, yields to given block; if defining new method, block defines its contents
74
- def method_missing(sym, *args, &block)
75
- super(sym, *args, &block)
76
- rescue NoMethodError
77
- # handling Constant look up to dynamically extend or add to element
78
- if lowercase?(sym)
79
- if (const = look_up_const) and const.is_a?(Module)
80
- extend const
81
- result = method(sym).call(*args)
82
- return(result) unless block_given?
83
- yield(result)
84
- elsif block_given?
85
- new_method = proc(&block)
86
- self.const_set(sym, new_method)
87
- return new_method.call *args
88
- else
89
- raise NoMethodError, "undefined method `#{sym.to_s}' for #{description}"
90
- end # if (const = look_up_const) ... elsif block_given? ... else ...
91
- else
92
- results = filter(sym, args)
93
- return results unless block_given?
94
- results.keep_if do |node| yield(node) end
95
- end # if lowercase? ... else ...
96
- end # def method_missing(sym, *args, &block)
97
-
98
- private
99
-
100
- # @param sym [Symbol] indicates which element type is being filtered for
101
- # @param args [several_variants] arguments for filtering element children that matched 'sym'
102
- # @return [[Element]] Elements of type 'sym' that match criteria 'args'
103
- def filter(sym, args)
104
- class_nodes = nodes.select do |node|
105
- node.name == sym.to_s.nmtokenize or simple_class(node) == sym.to_s
106
- end
107
- class_nodes.keep_if do |node|
108
- if args.empty?
109
- true
110
- else
111
- args.any? do |arg|
112
- if arg.is_a?(Hash)
113
- node[arg.first.first] == arg.first.last
114
- else
115
- !node[arg].nil?
116
- end
117
- end
118
- end # if args.empty? ... else ...
119
- end # class_nodes.keep_if do |node|
120
- end # def filter(args)
121
-
122
- # @param maudule [Module] module context in which to look for duck-called method's module
123
- # @return [Module, Class] requested module or class
124
- def look_up_const(maudule = Duxml)
125
- mod_names = name.split(':')
126
- until mod_names.empty?
127
- word = mod_names.shift
128
- k = word.constantize
129
- if maudule.const_defined?(k, true) or Module.const_defined?(simple_class, true)
130
- const = maudule.const_get(k)
131
- if const.is_a?(Module)
132
- maudule = const
133
- end
134
-
135
- return const if mod_names.empty? and [Module, Class].include?(const.class)
136
- end
137
- end
138
- nil
139
- end
140
-
141
- # @param sym [Symbol] symbol for a constant
142
- # @return [Boolean] is symbol lowercase?
143
- def lowercase?(sym)
144
- sym.to_s[0].match(/[A-Z]/).nil?
145
- end
146
-
147
- # @param obj [Object] usually Element
148
- # @return [String] name of final Class or Module of self
149
- def simple_class(obj=self)
150
- obj.class.to_s.split('::').last
151
- end
152
- end # module LazyOx
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + '/../ruby_ext/string')
4
+
5
+
6
+ module Duxml
7
+ module LazyOx
8
+ # welcome to Lazy-Ox - where any method that doesn't exist, you can create on the fly and assign its methods to
9
+ # a corresponding Duxml::Element. see Regexp.nmtoken and String#nmtokenize and String#constantize to see how a given symbol
10
+ # can be converted into XML element names and vice versa. it can also use Class names as method calls to return children by type
11
+ #
12
+ # this method uses Ox::Element's :method_missing but adds an additional rescue block that:
13
+ # matches namespaced Ruby module to this Element's name and extends this node with module's methods
14
+ # then method matching symbol is called again with given arguments, yielding result to block if given, returning result if not
15
+ # e.g.
16
+ # module Duxml
17
+ # module Throwable
18
+ # def throw
19
+ # puts 'throwing!!'
20
+ # end
21
+ # end
22
+ # end
23
+ #
24
+ # Element.new('throwable').throw => 'throwing!!'
25
+ #
26
+ # if symbol name matches a class then method yields to block or returns as array child nodes that matches class
27
+ # you can further refine search results by adding the symbol of the child instance variable, including name, by which to filter
28
+ # if block given, returns first child for which block evaluates to true
29
+ #
30
+ # e.g.
31
+ # class Child; end
32
+ #
33
+ # n = Element.new('node')
34
+ # n << 'text'
35
+ # n << Element.new('child')
36
+ # n << Element.new('child')
37
+ # n.Element # returns Array of Element nodes
38
+ # => [#<Duxml::Element:0x0002 @value="child" ...>,
39
+ # #<Duxml::Element:0x0003 @value="child" ...>]
40
+ #
41
+ # n.Element.each do |child| child << 'some text' end # adding some text
42
+ # => ['text',
43
+ # #<Duxml::Element:0x0002 @value="child" ... @nodes=['some text']>,
44
+ # #<Duxml::Element 0x0003 @value="child" ... @nodes=['some text']>]
45
+ #
46
+ # n.Element do |child| child.nodes.first == 'some text' end # returns all children for which block is true
47
+ # => [#<Duxml::Element:0x0002 @value="child" ... @nodes=['some text']>]
48
+ #
49
+ # %w(bar mar).each_with_index do |x, i| next if i.zero?; n.Child[:foo] = x end # adding some attributes
50
+ # => ['text',
51
+ # #<Duxml::Element:0x0002 @value="child" @attributes={foo: 'bar'} ...>,
52
+ # #<Duxml::Element:0x0003 @value="child" @attributes={foo: 'mar'} ...>]
53
+ #
54
+ # n.Element(:foo) # returns array of Child nodes with attribute :foo
55
+ # => [#<Duxml::Element:0x0002 @value="child" @attributes={foo: 'bar'} ...>,
56
+ # #<Duxml::Element:0x0003 @value="child" @attributes={foo: 'mar'} ...>]
57
+ #
58
+ # n.Element(foo: 'bar') # returns array of Child nodes with attribute :foo equal to 'bar'
59
+ # => [#<Duxml::Element:0xfff @value="child" @attributes={foo: 'bar'} ...>]
60
+ #
61
+ #
62
+ # if element name has no matching Class or Module in namespace,
63
+ # if symbol is lower case, it is made into a method, given &block as definition, then called with *args
64
+ # e.g. n.change_color('blue') do |new_color| => #<Duxml::Element:0xfff @value="node" @attributes={color: 'blue'} @nodes=[]>
65
+ # @color = new_color
66
+ # self
67
+ # end
68
+ # n.color => 'blue'
69
+ # n.change_color('mauve').color => 'mauve'
70
+ #
71
+ # @param sym [Symbol] method, class or module
72
+ # @param *args [*several_variants] either arguments to method or initializing values for instance of given class
73
+ # @param &block [block] if yielding result, yields to given block; if defining new method, block defines its contents
74
+ def method_missing(sym, *args, &block)
75
+ super(sym, *args, &block)
76
+ rescue NoMethodError
77
+ # handling Constant look up to dynamically extend or add to element
78
+ if lowercase?(sym)
79
+ if (const = look_up_const) and const.is_a?(Module)
80
+ extend const
81
+ result = method(sym).call(*args)
82
+ return(result) unless block_given?
83
+ yield(result)
84
+ elsif block_given?
85
+ new_method = proc(&block)
86
+ self.const_set(sym, new_method)
87
+ return new_method.call *args
88
+ else
89
+ raise NoMethodError, "undefined method `#{sym.to_s}' for #{description}"
90
+ end # if (const = look_up_const) ... elsif block_given? ... else ...
91
+ else
92
+ results = filter(sym, args)
93
+ return results unless block_given?
94
+ results.keep_if do |node| yield(node) end
95
+ end # if lowercase? ... else ...
96
+ end # def method_missing(sym, *args, &block)
97
+
98
+ private
99
+
100
+ # @param sym [Symbol] indicates which element type is being filtered for
101
+ # @param args [several_variants] arguments for filtering element children that matched 'sym'
102
+ # @return [[Element]] Elements of type 'sym' that match criteria 'args'
103
+ def filter(sym, args)
104
+ class_nodes = nodes.select do |node|
105
+ node.name == sym.to_s.nmtokenize or simple_class(node) == sym.to_s
106
+ end
107
+ class_nodes.keep_if do |node|
108
+ if args.empty?
109
+ true
110
+ else
111
+ args.any? do |arg|
112
+ if arg.is_a?(Hash)
113
+ node[arg.first.first] == arg.first.last
114
+ else
115
+ !node[arg].nil?
116
+ end
117
+ end
118
+ end # if args.empty? ... else ...
119
+ end # class_nodes.keep_if do |node|
120
+ end # def filter(args)
121
+
122
+ # @param maudule [Module] module context in which to look for duck-called method's module
123
+ # @return [Module, Class] requested module or class
124
+ def look_up_const(maudule = Duxml)
125
+ mod_names = name.split(':')
126
+ until mod_names.empty?
127
+ word = mod_names.shift
128
+ k = word.constantize
129
+ if maudule.const_defined?(k, true) or Module.const_defined?(simple_class, true)
130
+ const = maudule.const_get(k)
131
+ if const.is_a?(Module)
132
+ maudule = const
133
+ end
134
+
135
+ return const if mod_names.empty? and [Module, Class].include?(const.class)
136
+ end
137
+ end
138
+ nil
139
+ end
140
+
141
+ # @param sym [Symbol] symbol for a constant
142
+ # @return [Boolean] is symbol lowercase?
143
+ def lowercase?(sym)
144
+ sym.to_s[0].match(/[A-Z]/).nil?
145
+ end
146
+
147
+ # @param obj [Object] usually Element
148
+ # @return [String] name of final Class or Module of self
149
+ def simple_class(obj=self)
150
+ obj.class.to_s.split('::').last
151
+ end
152
+ end # module LazyOx
153
153
  end # module Duxml
@@ -1,39 +1,39 @@
1
- # Copyright (c) 2016 Freescale Semiconductor Inc.
2
-
3
- require 'observer'
4
-
5
- module Duxml
6
- # subclass of Array that is Observable by History
7
- # used to track changes in String nodes of XML Element
8
- class NodeSet < Array
9
- include Observable
10
-
11
- @parent
12
-
13
- attr_reader :parent
14
-
15
- # @param _parent [Element] Element that is parent to this NodeSet's elements
16
- # @param ary [[String, Element]] child nodes with which to initialize this NodeSet
17
- def initialize(_parent, ary=[])
18
- super ary
19
- @parent = _parent
20
- end
21
-
22
- # @return [HistoryClass] object that observes this NodeSet for changes
23
- def history
24
- @observer_peers.first.first if @observer_peers and @observer_peers.first.any?
25
- end
26
-
27
- # @param index [Fixnum] index of array where old String is to be replaced
28
- # @param str [String] replacing String
29
- # @return [self] reports old String and index to history
30
- def []=(index, str)
31
- raise Exception if count_observers < 1
32
- old_str = self[index]
33
- super(index, str)
34
- changed
35
- notify_observers(:ChangeText, parent, index, old_str)
36
- self
37
- end
38
- end # class NodeSet < Array
1
+ # Copyright (c) 2016 Freescale Semiconductor Inc.
2
+
3
+ require 'observer'
4
+
5
+ module Duxml
6
+ # subclass of Array that is Observable by History
7
+ # used to track changes in String nodes of XML Element
8
+ class NodeSet < Array
9
+ include Observable
10
+
11
+ @parent
12
+
13
+ attr_reader :parent
14
+
15
+ # @param _parent [Element] Element that is parent to this NodeSet's elements
16
+ # @param ary [[String, Element]] child nodes with which to initialize this NodeSet
17
+ def initialize(_parent, ary=[])
18
+ super ary
19
+ @parent = _parent
20
+ end
21
+
22
+ # @return [HistoryClass] object that observes this NodeSet for changes
23
+ def history
24
+ @observer_peers.first.first if @observer_peers and @observer_peers.first.any?
25
+ end
26
+
27
+ # @param index [Fixnum] index of array where old String is to be replaced
28
+ # @param str [String] replacing String
29
+ # @return [self] reports old String and index to history
30
+ def []=(index, str)
31
+ raise Exception if count_observers < 1
32
+ old_str = self[index]
33
+ super(index, str)
34
+ changed
35
+ notify_observers(:ChangeText, parent, index, old_str)
36
+ self
37
+ end
38
+ end # class NodeSet < Array
39
39
  end # module Duxml
data/lib/duxml/doc.rb CHANGED
@@ -1,26 +1,86 @@
1
1
  # Copyright (c) 2016 Freescale Semiconductor Inc.
2
2
 
3
3
  require File.expand_path(File.dirname(__FILE__) + '/doc/element')
4
+ require File.expand_path(File.dirname(__FILE__) + '/meta')
4
5
 
5
6
  module Duxml
6
7
  class Doc < ::Ox::Document
7
8
  include ElementGuts
9
+
10
+ # path of file where this Doc is saved to
11
+ @path
12
+
13
+ # meta data for this Doc; contains reference to grammar if it exists and history
14
+ @meta
15
+
16
+ attr_reader :meta, :path
17
+
8
18
  def initialize(prolog={})
9
19
  super(prolog)
10
20
  self[:version] ||= '1.0'
21
+ @meta = MetaClass.new
11
22
  @nodes = NodeSet.new(self)
12
- # TODO should also create new metadata!!
23
+ add_observer meta.history
13
24
  end
14
25
 
15
- def write_to(path)
16
- s = attributes.collect do |k, v| %( #{k}="#{v}") end.join
17
- %(<?xml #{s}?>)+nodes.first.to_s
18
- File.write(path, s)
19
- self
26
+ # @param _path [String] assigns file path to document, creating it if it does not already exist along with metadata file
27
+ def path=(_path)
28
+ @path = _path
29
+ set_meta _path unless path
30
+ unless File.exists?(path)
31
+ write_to(path)
32
+ end
20
33
  end
21
34
 
35
+ # @return [String] summary of XML document as Ruby object and description of root element
22
36
  def to_s
23
37
  "#<#{self.class.to_s} @object_id='#{object_id}' @root='#{root.nil? ? '' : root.description}'>"
24
38
  end
39
+
40
+ # @param path_or_obj [String, MetaClass] metadata object itself or path of metadata for this file; if none given, saves existing metadata to file using @path
41
+ # @return [Doc] self
42
+ def set_meta(path_or_obj=nil)
43
+ @meta = case path_or_obj
44
+ when MetaClass, Element then path_or_obj
45
+ when String && File.exists?(path_or_obj)
46
+ Ox.parse_obj(path_or_obj)
47
+ else
48
+ File.write(Meta.meta_path(path), Ox.dump(meta)) if path
49
+ meta
50
+ end
51
+ self
52
+ end
53
+
54
+ # shortcut method @see Meta#grammar
55
+ def grammar
56
+ meta.grammar
57
+ end
58
+
59
+ # shortcut method @see Meta#grammar=
60
+ def grammar=(grammar_or_file)
61
+ meta.grammar = grammar_or_file
62
+ end
63
+
64
+ # shortcut method @see Meta#history
65
+ def history
66
+ meta.history
67
+ end
68
+
69
+ # @return [String] one word description of what this object is: 'document'
70
+ def description
71
+ 'document'
72
+ end
73
+
74
+ # @param path [String] document's file path
75
+ # @return [Doc] returns self after writing contents to file
76
+ def write_to(path)
77
+ s = attributes.collect do |k, v| %( #{k}="#{v}") end.join
78
+ File.write(path, %(<?xml #{s}?>\n) + root.to_s)
79
+ x = meta.xml
80
+ File.write(Meta.meta_path(path), meta.xml.to_s)
81
+ self
82
+ end
25
83
  end # class Document < Element
26
- end
84
+ end
85
+
86
+ Hash
@@ -31,6 +31,20 @@ module Duxml
31
31
  module Pattern
32
32
  include Duxml
33
33
 
34
+ def xml
35
+ p = Element.new(simple_name)
36
+ instance_variables.each do |sym|
37
+ val = instance_variable_get(sym)
38
+ if val.respond_to?(:nodes)
39
+ d = Element.new(sym.to_s) << val
40
+ p << d
41
+ else
42
+ p[sym.to_s[1..-1].to_sym] = val.to_s unless sym == :@observer_peers
43
+ end
44
+ end
45
+ p
46
+ end
47
+
34
48
  # @return [String] nmtoken name of this pattern without namespace prefix e.g. ChildPattern.new(parent, child).name => 'child_pattern'
35
49
  def simple_name
36
50
  name.split(':').last