source: extensions/gsdl-video/trunk/installed/cmdline/lib/ruby/1.8/wsdl/xmlSchema/parser.rb@ 18425

Last change on this file since 18425 was 18425, checked in by davidb, 15 years ago

Video extension to Greenstone

File size: 3.9 KB
Line 
1# WSDL4R - WSDL XML Instance parser library.
2# Copyright (C) 2002, 2003, 2005 NAKAMURA, Hiroshi <[email protected]>.
3
4# This program is copyrighted free software by NAKAMURA, Hiroshi. You can
5# redistribute it and/or modify it under the same terms of Ruby's license;
6# either the dual license version in 2003, or any later version.
7
8
9require 'xsd/qname'
10require 'xsd/ns'
11require 'xsd/charset'
12require 'xsd/datatypes'
13require 'xsd/xmlparser'
14require 'wsdl/xmlSchema/data'
15
16
17module WSDL
18module XMLSchema
19
20
21class Parser
22 include XSD
23
24 class ParseError < Error; end
25 class FormatDecodeError < ParseError; end
26 class UnknownElementError < FormatDecodeError; end
27 class UnknownAttributeError < FormatDecodeError; end
28 class UnexpectedElementError < FormatDecodeError; end
29 class ElementConstraintError < FormatDecodeError; end
30 class AttributeConstraintError < FormatDecodeError; end
31
32private
33
34 class ParseFrame
35 attr_reader :ns
36 attr_reader :name
37 attr_accessor :node
38
39 private
40
41 def initialize(ns, name, node)
42 @ns = ns
43 @name = name
44 @node = node
45 end
46 end
47
48public
49
50 def initialize(opt = {})
51 @parser = XSD::XMLParser.create_parser(self, opt)
52 @parsestack = nil
53 @lastnode = nil
54 @ignored = {}
55 @location = opt[:location]
56 @originalroot = opt[:originalroot]
57 end
58
59 def parse(string_or_readable)
60 @parsestack = []
61 @lastnode = nil
62 @textbuf = ''
63 @parser.do_parse(string_or_readable)
64 @lastnode
65 end
66
67 def charset
68 @parser.charset
69 end
70
71 def start_element(name, attrs)
72 lastframe = @parsestack.last
73 ns = parent = nil
74 if lastframe
75 ns = lastframe.ns.clone_ns
76 parent = lastframe.node
77 else
78 ns = XSD::NS.new
79 parent = nil
80 end
81 attrs = XSD::XMLParser.filter_ns(ns, attrs)
82 node = decode_tag(ns, name, attrs, parent)
83 @parsestack << ParseFrame.new(ns, name, node)
84 end
85
86 def characters(text)
87 lastframe = @parsestack.last
88 if lastframe
89 # Need not to be cloned because character does not have attr.
90 ns = lastframe.ns
91 decode_text(ns, text)
92 else
93 p text if $DEBUG
94 end
95 end
96
97 def end_element(name)
98 lastframe = @parsestack.pop
99 unless name == lastframe.name
100 raise UnexpectedElementError.new("closing element name '#{name}' does not match with opening element '#{lastframe.name}'")
101 end
102 decode_tag_end(lastframe.ns, lastframe.node)
103 @lastnode = lastframe.node
104 end
105
106private
107
108 def decode_tag(ns, name, attrs, parent)
109 o = nil
110 elename = ns.parse(name)
111 if !parent
112 if elename == SchemaName
113 o = Schema.parse_element(elename)
114 o.location = @location
115 else
116 raise UnknownElementError.new("unknown element: #{elename}")
117 end
118 o.root = @originalroot if @originalroot # o.root = o otherwise
119 else
120 if elename == AnnotationName
121 # only the first annotation element is allowed for each element.
122 o = Annotation.new
123 else
124 o = parent.parse_element(elename)
125 end
126 unless o
127 unless @ignored.key?(elename)
128 warn("ignored element: #{elename} of #{parent.class}")
129 @ignored[elename] = elename
130 end
131 o = Documentation.new # which accepts any element.
132 end
133 # node could be a pseudo element. pseudo element has its own parent.
134 o.root = parent.root
135 o.parent = parent if o.parent.nil?
136 end
137 attrs.each do |key, value|
138 attr_ele = ns.parse(key, true)
139 value_ele = ns.parse(value, true)
140 value_ele.source = value # for recovery; value may not be a QName
141 if attr_ele == IdAttrName
142 o.id = value_ele
143 else
144 unless o.parse_attr(attr_ele, value_ele)
145 unless @ignored.key?(attr_ele)
146 warn("ignored attr: #{attr_ele}")
147 @ignored[attr_ele] = attr_ele
148 end
149 end
150 end
151 end
152 o
153 end
154
155 def decode_tag_end(ns, node)
156 node.parse_epilogue
157 end
158
159 def decode_text(ns, text)
160 @textbuf << text
161 end
162end
163
164
165end
166end
Note: See TracBrowser for help on using the repository browser.