nokogiri 1.2.3 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of nokogiri might be problematic. Click here for more details.
- data/.autotest +14 -2
- data/CHANGELOG.ja.rdoc +38 -0
- data/CHANGELOG.rdoc +43 -0
- data/Manifest.txt +80 -5
- data/README.ja.rdoc +12 -11
- data/README.rdoc +4 -2
- data/Rakefile +103 -173
- data/bin/nokogiri +47 -0
- data/ext/nokogiri/extconf.rb +19 -13
- data/ext/nokogiri/html_document.c +39 -3
- data/ext/nokogiri/html_document.h +1 -1
- data/ext/nokogiri/html_element_description.c +272 -0
- data/ext/nokogiri/html_element_description.h +10 -0
- data/ext/nokogiri/html_entity_lookup.h +1 -1
- data/ext/nokogiri/html_sax_parser.h +1 -1
- data/ext/nokogiri/{native.c → nokogiri.c} +11 -3
- data/ext/nokogiri/{native.h → nokogiri.h} +18 -4
- data/ext/nokogiri/xml_attr.c +14 -5
- data/ext/nokogiri/xml_attr.h +1 -1
- data/ext/nokogiri/xml_cdata.c +15 -6
- data/ext/nokogiri/xml_cdata.h +1 -1
- data/ext/nokogiri/xml_comment.c +13 -4
- data/ext/nokogiri/xml_comment.h +1 -1
- data/ext/nokogiri/xml_document.c +50 -41
- data/ext/nokogiri/xml_document.h +1 -1
- data/ext/nokogiri/xml_document_fragment.c +12 -4
- data/ext/nokogiri/xml_document_fragment.h +1 -1
- data/ext/nokogiri/xml_dtd.c +1 -1
- data/ext/nokogiri/xml_dtd.h +1 -1
- data/ext/nokogiri/xml_entity_reference.c +13 -4
- data/ext/nokogiri/xml_entity_reference.h +1 -1
- data/ext/nokogiri/xml_io.h +1 -1
- data/ext/nokogiri/xml_namespace.c +69 -0
- data/ext/nokogiri/xml_namespace.h +12 -0
- data/ext/nokogiri/xml_node.c +232 -124
- data/ext/nokogiri/xml_node.h +3 -4
- data/ext/nokogiri/xml_node_set.c +206 -19
- data/ext/nokogiri/xml_node_set.h +1 -1
- data/ext/nokogiri/xml_processing_instruction.c +14 -4
- data/ext/nokogiri/xml_processing_instruction.h +1 -1
- data/ext/nokogiri/xml_reader.c +87 -7
- data/ext/nokogiri/xml_reader.h +1 -1
- data/ext/nokogiri/xml_relax_ng.c +106 -0
- data/ext/nokogiri/xml_relax_ng.h +9 -0
- data/ext/nokogiri/xml_sax_parser.c +122 -2
- data/ext/nokogiri/xml_sax_parser.h +1 -1
- data/ext/nokogiri/xml_sax_push_parser.c +1 -0
- data/ext/nokogiri/xml_sax_push_parser.h +1 -1
- data/ext/nokogiri/xml_schema.c +107 -0
- data/ext/nokogiri/xml_schema.h +9 -0
- data/ext/nokogiri/xml_syntax_error.h +1 -1
- data/ext/nokogiri/xml_text.c +10 -3
- data/ext/nokogiri/xml_text.h +1 -1
- data/ext/nokogiri/xml_xpath.h +1 -1
- data/ext/nokogiri/xml_xpath_context.h +1 -1
- data/ext/nokogiri/xslt_stylesheet.c +29 -16
- data/ext/nokogiri/xslt_stylesheet.h +1 -1
- data/lib/action-nokogiri.rb +7 -1
- data/lib/nokogiri.rb +21 -5
- data/lib/nokogiri/css/generated_parser.rb +49 -14
- data/lib/nokogiri/css/generated_tokenizer.rb +2 -2
- data/lib/nokogiri/css/node.rb +13 -3
- data/lib/nokogiri/css/parser.rb +8 -0
- data/lib/nokogiri/css/parser.y +7 -7
- data/lib/nokogiri/css/tokenizer.rb +2 -0
- data/lib/nokogiri/css/xpath_visitor.rb +10 -6
- data/lib/nokogiri/decorators/hpricot/node.rb +1 -1
- data/lib/nokogiri/decorators/hpricot/node_set.rb +2 -2
- data/lib/nokogiri/decorators/hpricot/xpath_visitor.rb +2 -0
- data/lib/nokogiri/decorators/slop.rb +3 -1
- data/lib/nokogiri/ffi/html/document.rb +37 -0
- data/lib/nokogiri/ffi/html/element_description.rb +85 -0
- data/lib/nokogiri/ffi/html/entity_lookup.rb +16 -0
- data/lib/nokogiri/ffi/html/sax/parser.rb +21 -0
- data/lib/nokogiri/ffi/io_callbacks.rb +32 -0
- data/lib/nokogiri/ffi/libxml.rb +314 -0
- data/lib/nokogiri/ffi/structs/common_node.rb +26 -0
- data/lib/nokogiri/ffi/structs/html_elem_desc.rb +24 -0
- data/lib/nokogiri/ffi/structs/html_entity_desc.rb +13 -0
- data/lib/nokogiri/ffi/structs/xml_alloc.rb +16 -0
- data/lib/nokogiri/ffi/structs/xml_attr.rb +19 -0
- data/lib/nokogiri/ffi/structs/xml_buffer.rb +16 -0
- data/lib/nokogiri/ffi/structs/xml_document.rb +108 -0
- data/lib/nokogiri/ffi/structs/xml_dtd.rb +26 -0
- data/lib/nokogiri/ffi/structs/xml_node.rb +28 -0
- data/lib/nokogiri/ffi/structs/xml_node_set.rb +53 -0
- data/lib/nokogiri/ffi/structs/xml_notation.rb +11 -0
- data/lib/nokogiri/ffi/structs/xml_ns.rb +15 -0
- data/lib/nokogiri/ffi/structs/xml_relax_ng.rb +14 -0
- data/lib/nokogiri/ffi/structs/xml_sax_handler.rb +51 -0
- data/lib/nokogiri/ffi/structs/xml_sax_push_parser_context.rb +14 -0
- data/lib/nokogiri/ffi/structs/xml_schema.rb +13 -0
- data/lib/nokogiri/ffi/structs/xml_syntax_error.rb +31 -0
- data/lib/nokogiri/ffi/structs/xml_text_reader.rb +12 -0
- data/lib/nokogiri/ffi/structs/xml_xpath_context.rb +37 -0
- data/lib/nokogiri/ffi/structs/xml_xpath_object.rb +35 -0
- data/lib/nokogiri/ffi/structs/xml_xpath_parser_context.rb +20 -0
- data/lib/nokogiri/ffi/structs/xslt_stylesheet.rb +13 -0
- data/lib/nokogiri/ffi/xml/attr.rb +41 -0
- data/lib/nokogiri/ffi/xml/cdata.rb +19 -0
- data/lib/nokogiri/ffi/xml/comment.rb +18 -0
- data/lib/nokogiri/ffi/xml/document.rb +107 -0
- data/lib/nokogiri/ffi/xml/document_fragment.rb +26 -0
- data/lib/nokogiri/ffi/xml/dtd.rb +42 -0
- data/lib/nokogiri/ffi/xml/entity_reference.rb +19 -0
- data/lib/nokogiri/ffi/xml/namespace.rb +38 -0
- data/lib/nokogiri/ffi/xml/node.rb +380 -0
- data/lib/nokogiri/ffi/xml/node_set.rb +130 -0
- data/lib/nokogiri/ffi/xml/processing_instruction.rb +20 -0
- data/lib/nokogiri/ffi/xml/reader.rb +217 -0
- data/lib/nokogiri/ffi/xml/relax_ng.rb +51 -0
- data/lib/nokogiri/ffi/xml/sax/parser.rb +148 -0
- data/lib/nokogiri/ffi/xml/sax/push_parser.rb +38 -0
- data/lib/nokogiri/ffi/xml/schema.rb +55 -0
- data/lib/nokogiri/ffi/xml/syntax_error.rb +76 -0
- data/lib/nokogiri/ffi/xml/text.rb +18 -0
- data/lib/nokogiri/ffi/xml/xpath.rb +19 -0
- data/lib/nokogiri/ffi/xml/xpath_context.rb +135 -0
- data/lib/nokogiri/ffi/xslt/stylesheet.rb +47 -0
- data/lib/nokogiri/hpricot.rb +14 -3
- data/lib/nokogiri/html.rb +11 -46
- data/lib/nokogiri/html/builder.rb +27 -1
- data/lib/nokogiri/html/document.rb +62 -6
- data/lib/nokogiri/html/document_fragment.rb +15 -0
- data/lib/nokogiri/html/element_description.rb +23 -0
- data/lib/nokogiri/html/entity_lookup.rb +2 -0
- data/lib/nokogiri/html/sax/parser.rb +27 -1
- data/lib/nokogiri/version.rb +26 -1
- data/lib/nokogiri/version_warning.rb +11 -0
- data/lib/nokogiri/xml.rb +25 -51
- data/lib/nokogiri/xml/builder.rb +166 -10
- data/lib/nokogiri/xml/cdata.rb +3 -1
- data/lib/nokogiri/xml/document.rb +39 -6
- data/lib/nokogiri/xml/document_fragment.rb +41 -1
- data/lib/nokogiri/xml/dtd.rb +3 -1
- data/lib/nokogiri/xml/entity_declaration.rb +3 -1
- data/lib/nokogiri/xml/fragment_handler.rb +24 -3
- data/lib/nokogiri/xml/namespace.rb +7 -0
- data/lib/nokogiri/xml/node.rb +314 -65
- data/lib/nokogiri/xml/node/save_options.rb +12 -2
- data/lib/nokogiri/xml/node_set.rb +58 -8
- data/lib/nokogiri/xml/parse_options.rb +80 -0
- data/lib/nokogiri/xml/processing_instruction.rb +2 -0
- data/lib/nokogiri/xml/reader.rb +42 -3
- data/lib/nokogiri/xml/relax_ng.rb +32 -0
- data/lib/nokogiri/xml/sax.rb +0 -7
- data/lib/nokogiri/xml/sax/document.rb +84 -0
- data/lib/nokogiri/xml/sax/parser.rb +38 -2
- data/lib/nokogiri/xml/sax/push_parser.rb +12 -0
- data/lib/nokogiri/xml/schema.rb +65 -0
- data/lib/nokogiri/xml/syntax_error.rb +11 -0
- data/lib/nokogiri/xml/xpath.rb +1 -1
- data/lib/nokogiri/xml/xpath_context.rb +2 -0
- data/lib/nokogiri/xslt.rb +21 -1
- data/lib/nokogiri/xslt/stylesheet.rb +19 -0
- data/lib/xsd/xmlparser/nokogiri.rb +12 -2
- data/tasks/test.rb +42 -19
- data/test/css/test_parser.rb +29 -0
- data/test/ffi/test_document.rb +35 -0
- data/test/files/address_book.rlx +12 -0
- data/test/files/address_book.xml +10 -0
- data/test/files/po.xml +32 -0
- data/test/files/po.xsd +66 -0
- data/test/helper.rb +38 -8
- data/test/html/sax/test_parser.rb +12 -0
- data/test/html/test_builder.rb +25 -2
- data/test/html/test_document.rb +91 -20
- data/test/html/test_document_fragment.rb +97 -0
- data/test/html/test_element_description.rb +95 -0
- data/test/html/test_node.rb +66 -3
- data/test/test_convert_xpath.rb +1 -1
- data/test/test_memory_leak.rb +57 -18
- data/test/test_nokogiri.rb +24 -2
- data/test/test_reader.rb +77 -0
- data/test/test_xslt_transforms.rb +120 -82
- data/test/xml/node/test_subclass.rb +44 -0
- data/test/xml/sax/test_parser.rb +9 -0
- data/test/xml/sax/test_push_parser.rb +24 -0
- data/test/xml/test_attr.rb +7 -0
- data/test/xml/test_builder.rb +48 -0
- data/test/xml/test_cdata.rb +19 -0
- data/test/xml/test_comment.rb +6 -0
- data/test/xml/test_document.rb +101 -2
- data/test/xml/test_document_fragment.rb +55 -3
- data/test/xml/test_entity_reference.rb +4 -0
- data/test/xml/test_namespace.rb +43 -0
- data/test/xml/test_node.rb +255 -8
- data/test/xml/test_node_attributes.rb +34 -0
- data/test/xml/test_node_encoding.rb +9 -2
- data/test/xml/test_node_set.rb +197 -1
- data/test/xml/test_parse_options.rb +52 -0
- data/test/xml/test_processing_instruction.rb +5 -0
- data/test/xml/test_relax_ng.rb +60 -0
- data/test/xml/test_schema.rb +65 -0
- data/test/xml/test_text.rb +5 -0
- data/test/xml/test_unparented_node.rb +3 -3
- metadata +128 -12
- data/lib/nokogiri/xml/comment.rb +0 -6
- data/lib/nokogiri/xml/element.rb +0 -6
- data/lib/nokogiri/xml/text.rb +0 -6
@@ -0,0 +1,20 @@
|
|
1
|
+
module Nokogiri
|
2
|
+
module XML
|
3
|
+
class ProcessingInstruction < Node
|
4
|
+
|
5
|
+
attr_accessor :cstruct # :nodoc:
|
6
|
+
|
7
|
+
def self.new(document, name, content, *rest) # :nodoc:
|
8
|
+
node_ptr = LibXML.xmlNewDocPI(document.cstruct, name.to_s, content.to_s)
|
9
|
+
node_cstruct = LibXML::XmlNode.new(node_ptr)
|
10
|
+
node_cstruct.keep_reference_from_document!
|
11
|
+
|
12
|
+
node = Node.wrap(node_cstruct, self)
|
13
|
+
node.send :initialize, document, name, content, *rest
|
14
|
+
yield node if block_given?
|
15
|
+
node
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,217 @@
|
|
1
|
+
module Nokogiri
|
2
|
+
module XML
|
3
|
+
class Reader
|
4
|
+
|
5
|
+
attr_accessor :cstruct # :nodoc:
|
6
|
+
attr_accessor :reader_callback # :nodoc:
|
7
|
+
|
8
|
+
def default? # :nodoc:
|
9
|
+
LibXML.xmlTextReaderIsDefault(cstruct) == 1
|
10
|
+
end
|
11
|
+
|
12
|
+
def value? # :nodoc:
|
13
|
+
LibXML.xmlTextReaderHasValue(cstruct) == 1
|
14
|
+
end
|
15
|
+
|
16
|
+
def attributes? # :nodoc:
|
17
|
+
# this implementation of xmlTextReaderHasAttributes explicitly includes
|
18
|
+
# namespaces and properties, because some earlier versions ignore
|
19
|
+
# namespaces.
|
20
|
+
node_ptr = LibXML.xmlTextReaderCurrentNode(cstruct)
|
21
|
+
return false if node_ptr.null?
|
22
|
+
node = LibXML::XmlNode.new node_ptr
|
23
|
+
node[:type] == Node::ELEMENT_NODE && (!node[:properties].null? || !node[:nsDef].null?)
|
24
|
+
end
|
25
|
+
|
26
|
+
def namespaces # :nodoc:
|
27
|
+
return {} unless attributes?
|
28
|
+
|
29
|
+
ptr = LibXML.xmlTextReaderExpand(cstruct)
|
30
|
+
return nil if ptr.null?
|
31
|
+
|
32
|
+
node = Node.wrap(ptr)
|
33
|
+
Reader.node_namespaces(node)
|
34
|
+
end
|
35
|
+
|
36
|
+
def attribute_nodes # :nodoc:
|
37
|
+
return {} unless attributes?
|
38
|
+
|
39
|
+
ptr = LibXML.xmlTextReaderExpand(cstruct)
|
40
|
+
return nil if ptr.null?
|
41
|
+
node_struct = LibXML::XmlNode.new(ptr)
|
42
|
+
|
43
|
+
# FIXME I'm not sure if this is correct..... I don't really like pointing
|
44
|
+
# at this document, but I have to because of the assertions in
|
45
|
+
# the node wrapping code.
|
46
|
+
unless node_struct.document.ruby_doc
|
47
|
+
doc_struct = LibXML::XmlDocumentCast.new(node_struct[:doc])
|
48
|
+
doc_struct.alloc_tuple
|
49
|
+
doc = Document.wrap(doc_struct)
|
50
|
+
end
|
51
|
+
|
52
|
+
node = Node.wrap(node_struct)
|
53
|
+
node.attribute_nodes
|
54
|
+
end
|
55
|
+
|
56
|
+
def attribute_at(index) # :nodoc:
|
57
|
+
return nil if index.nil?
|
58
|
+
index = index.to_i
|
59
|
+
attr_ptr = LibXML.xmlTextReaderGetAttributeNo(cstruct, index)
|
60
|
+
return nil if attr_ptr.null?
|
61
|
+
|
62
|
+
attr = attr_ptr.read_string
|
63
|
+
LibXML.xmlFree attr_ptr
|
64
|
+
attr
|
65
|
+
end
|
66
|
+
|
67
|
+
def attribute(name) # :nodoc:
|
68
|
+
return nil if name.nil?
|
69
|
+
attr_ptr = LibXML.xmlTextReaderGetAttribute(cstruct, name.to_s)
|
70
|
+
if attr_ptr.null?
|
71
|
+
# this section is an attempt to workaround older versions of libxml that
|
72
|
+
# don't handle namespaces properly in all attribute-and-friends functions
|
73
|
+
prefix_ptr = FFI::MemoryPointer.new :pointer
|
74
|
+
localname = LibXML.xmlSplitQName2(name, prefix_ptr)
|
75
|
+
prefix = prefix_ptr.get_pointer(0)
|
76
|
+
if ! localname.null?
|
77
|
+
attr_ptr = LibXML.xmlTextReaderLookupNamespace(cstruct, localname.read_string)
|
78
|
+
LibXML.xmlFree(localname)
|
79
|
+
else
|
80
|
+
if prefix.null? || prefix.read_string.length == 0
|
81
|
+
attr_ptr = LibXML.xmlTextReaderLookupNamespace(cstruct, nil)
|
82
|
+
else
|
83
|
+
attr_ptr = LibXML.xmlTextReaderLookupNamespace(cstruct, prefix.read_string)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
LibXML.xmlFree(prefix)
|
87
|
+
end
|
88
|
+
return nil if attr_ptr.null?
|
89
|
+
|
90
|
+
attr = attr_ptr.read_string
|
91
|
+
LibXML.xmlFree(attr_ptr)
|
92
|
+
attr
|
93
|
+
end
|
94
|
+
|
95
|
+
def attribute_count # :nodoc:
|
96
|
+
count = LibXML.xmlTextReaderAttributeCount(cstruct)
|
97
|
+
count == -1 ? nil : count
|
98
|
+
end
|
99
|
+
|
100
|
+
def depth # :nodoc:
|
101
|
+
val = LibXML.xmlTextReaderDepth(cstruct)
|
102
|
+
val == -1 ? nil : val
|
103
|
+
end
|
104
|
+
|
105
|
+
def xml_version # :nodoc:
|
106
|
+
val = LibXML.xmlTextReaderConstXmlVersion(cstruct)
|
107
|
+
val.null? ? nil : val.read_string
|
108
|
+
end
|
109
|
+
|
110
|
+
def lang # :nodoc:
|
111
|
+
val = LibXML.xmlTextReaderConstXmlLang(cstruct)
|
112
|
+
val.null? ? nil : val.read_string
|
113
|
+
end
|
114
|
+
|
115
|
+
def value # :nodoc:
|
116
|
+
val = LibXML.xmlTextReaderConstValue(cstruct)
|
117
|
+
val.null? ? nil : val.read_string
|
118
|
+
end
|
119
|
+
|
120
|
+
def prefix # :nodoc:
|
121
|
+
val = LibXML.xmlTextReaderConstPrefix(cstruct)
|
122
|
+
val.null? ? nil : val.read_string
|
123
|
+
end
|
124
|
+
|
125
|
+
def namespace_uri # :nodoc:
|
126
|
+
val = LibXML.xmlTextReaderConstNamespaceUri(cstruct)
|
127
|
+
val.null? ? nil : val.read_string
|
128
|
+
end
|
129
|
+
|
130
|
+
def local_name # :nodoc:
|
131
|
+
val = LibXML.xmlTextReaderConstLocalName(cstruct)
|
132
|
+
val.null? ? nil : val.read_string
|
133
|
+
end
|
134
|
+
|
135
|
+
def name # :nodoc:
|
136
|
+
val = LibXML.xmlTextReaderConstName(cstruct)
|
137
|
+
val.null? ? nil : val.read_string
|
138
|
+
end
|
139
|
+
|
140
|
+
def state # :nodoc:
|
141
|
+
LibXML.xmlTextReaderReadState(cstruct)
|
142
|
+
end
|
143
|
+
|
144
|
+
def read # :nodoc:
|
145
|
+
error_list = self.errors
|
146
|
+
|
147
|
+
LibXML.xmlSetStructuredErrorFunc(nil, SyntaxError.error_array_pusher(error_list))
|
148
|
+
ret = LibXML.xmlTextReaderRead(cstruct)
|
149
|
+
LibXML.xmlSetStructuredErrorFunc(nil, nil)
|
150
|
+
|
151
|
+
return self if ret == 1
|
152
|
+
return nil if ret == 0
|
153
|
+
|
154
|
+
error = LibXML.xmlGetLastError()
|
155
|
+
if error
|
156
|
+
raise SyntaxError.wrap(error)
|
157
|
+
else
|
158
|
+
raise RuntimeError, "Error pulling: #{ret}"
|
159
|
+
end
|
160
|
+
|
161
|
+
nil
|
162
|
+
end
|
163
|
+
|
164
|
+
def self.from_memory(buffer, url=nil, encoding=nil, options=0) # :nodoc:
|
165
|
+
raise(ArgumentError, "string cannot be nil") if buffer.nil?
|
166
|
+
|
167
|
+
memory = FFI::MemoryPointer.new(buffer.length) # we need to manage native memory lifecycle
|
168
|
+
memory.put_bytes(0, buffer)
|
169
|
+
reader_ptr = LibXML.xmlReaderForMemory(memory, memory.total, url, encoding, options)
|
170
|
+
raise(RuntimeError, "couldn't create a reader") if reader_ptr.null?
|
171
|
+
|
172
|
+
reader = allocate
|
173
|
+
reader.cstruct = LibXML::XmlTextReader.new(reader_ptr)
|
174
|
+
reader.send(:initialize, memory, url, encoding)
|
175
|
+
reader
|
176
|
+
end
|
177
|
+
|
178
|
+
def self.from_io(io, url=nil, encoding=nil, options=0) # :nodoc:
|
179
|
+
raise(ArgumentError, "io cannot be nil") if io.nil?
|
180
|
+
|
181
|
+
cb = IoCallbacks.reader(io) # we will keep a reference to prevent it from being GC'd
|
182
|
+
reader_ptr = LibXML.xmlReaderForIO(cb, nil, nil, url, encoding, options)
|
183
|
+
raise "couldn't create a parser" if reader_ptr.null?
|
184
|
+
|
185
|
+
reader = allocate
|
186
|
+
reader.cstruct = LibXML::XmlTextReader.new(reader_ptr)
|
187
|
+
reader.send(:initialize, io, url, encoding)
|
188
|
+
reader.reader_callback = cb
|
189
|
+
reader
|
190
|
+
end
|
191
|
+
|
192
|
+
private
|
193
|
+
|
194
|
+
class << self
|
195
|
+
def node_namespaces(node) # :nodoc:
|
196
|
+
cstruct = node.cstruct
|
197
|
+
ahash = {}
|
198
|
+
return ahash unless cstruct[:type] == Node::ELEMENT_NODE
|
199
|
+
ns = cstruct[:nsDef]
|
200
|
+
while ! ns.null?
|
201
|
+
ns_cstruct = LibXML::XmlNs.new(ns)
|
202
|
+
prefix = ns_cstruct[:prefix]
|
203
|
+
key = if prefix.nil? || prefix.empty?
|
204
|
+
"xmlns"
|
205
|
+
else
|
206
|
+
"xmlns:#{prefix}"
|
207
|
+
end
|
208
|
+
ahash[key] = ns_cstruct[:href] # TODO: encoding?
|
209
|
+
ns = ns_cstruct[:next] # TODO: encoding?
|
210
|
+
end
|
211
|
+
ahash
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Nokogiri
|
2
|
+
module XML
|
3
|
+
class RelaxNG < Schema
|
4
|
+
def validate_document(document) # :nodoc:
|
5
|
+
errors = []
|
6
|
+
|
7
|
+
ctx = LibXML.xmlRelaxNGNewValidCtxt(cstruct)
|
8
|
+
raise RuntimeError.new("Could not create a validation context") if ctx.null?
|
9
|
+
|
10
|
+
LibXML.xmlRelaxNGSetValidStructuredErrors(ctx,
|
11
|
+
SyntaxError.error_array_pusher(errors), nil) unless Nokogiri.is_2_6_16?
|
12
|
+
|
13
|
+
LibXML.xmlRelaxNGValidateDoc(ctx, document.cstruct)
|
14
|
+
|
15
|
+
LibXML.xmlRelaxNGFreeValidCtxt(ctx)
|
16
|
+
|
17
|
+
errors
|
18
|
+
end
|
19
|
+
private :validate_document
|
20
|
+
|
21
|
+
def self.read_memory(content) # :nodoc:
|
22
|
+
ctx = LibXML.xmlRelaxNGNewMemParserCtxt(content, content.length)
|
23
|
+
|
24
|
+
errors = []
|
25
|
+
|
26
|
+
LibXML.xmlSetStructuredErrorFunc(nil, SyntaxError.error_array_pusher(errors))
|
27
|
+
LibXML.xmlRelaxNGSetParserStructuredErrors(
|
28
|
+
ctx, SyntaxError.error_array_pusher(errors), nil) unless Nokogiri.is_2_6_16?
|
29
|
+
|
30
|
+
schema_ptr = LibXML.xmlRelaxNGParse(ctx)
|
31
|
+
|
32
|
+
LibXML.xmlSetStructuredErrorFunc(nil, nil)
|
33
|
+
LibXML.xmlRelaxNGFreeParserCtxt(ctx)
|
34
|
+
|
35
|
+
if schema_ptr.null?
|
36
|
+
error = LibXML.xmlGetLastError
|
37
|
+
if error
|
38
|
+
raise SyntaxError.wrap(error)
|
39
|
+
else
|
40
|
+
raise RuntimeError, "Could not parse document"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
schema = allocate
|
45
|
+
schema.cstruct = LibXML::XmlRelaxNG.new schema_ptr
|
46
|
+
schema.errors = errors
|
47
|
+
schema
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
module Nokogiri
|
2
|
+
module XML
|
3
|
+
module SAX
|
4
|
+
class Parser
|
5
|
+
|
6
|
+
attr_accessor :cstruct # :nodoc:
|
7
|
+
|
8
|
+
def parse_memory(data) # :nodoc:
|
9
|
+
raise(ArgumentError, 'data cannot be nil') if data.nil?
|
10
|
+
LibXML.xmlSAXUserParseMemory(cstruct, nil, data, data.length)
|
11
|
+
data
|
12
|
+
end
|
13
|
+
|
14
|
+
def native_parse_io(io, encoding) # :nodoc:
|
15
|
+
sax_ctx = LibXML.xmlCreateIOParserCtxt(cstruct, nil, IoCallbacks.reader(io), nil, nil, encoding)
|
16
|
+
LibXML.xmlParseDocument(sax_ctx)
|
17
|
+
LibXML.xmlFreeParserCtxt(sax_ctx)
|
18
|
+
io
|
19
|
+
end
|
20
|
+
|
21
|
+
def native_parse_file(data) # :nodoc:
|
22
|
+
LibXML.xmlSAXUserParseFile(cstruct, nil, data)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.new(doc = XML::SAX::Document.new, encoding = 'ASCII') # :nodoc:
|
26
|
+
parser = allocate
|
27
|
+
parser.document = doc
|
28
|
+
parser.encoding = encoding
|
29
|
+
parser.cstruct = LibXML::XmlSaxHandler.allocate
|
30
|
+
parser.send(:setup_lambdas)
|
31
|
+
parser
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def setup_lambdas # :nodoc:
|
37
|
+
@closures = {} # we need to keep references to the closures to avoid GC
|
38
|
+
|
39
|
+
[ :startDocument, :endDocument, :startElement, :endElement, :characters,
|
40
|
+
:comment, :warning, :error, :cdataBlock, :startElementNs, :endElementNs ].each do |sym|
|
41
|
+
@closures[sym] = lambda { |*args| send("__internal__#{sym}", *args) } # "i'm your private dancer", etc.
|
42
|
+
end
|
43
|
+
|
44
|
+
@closures.each { |k,v| cstruct[k] = v }
|
45
|
+
|
46
|
+
cstruct[:initialized] = Nokogiri::LibXML::XmlSaxHandler::XML_SAX2_MAGIC
|
47
|
+
end
|
48
|
+
|
49
|
+
def __internal__startDocument(_) # :nodoc:
|
50
|
+
@document.start_document
|
51
|
+
end
|
52
|
+
|
53
|
+
def __internal__endDocument(_) # :nodoc:
|
54
|
+
@document.end_document
|
55
|
+
end
|
56
|
+
|
57
|
+
def __internal__startElement(_, name, attributes) # :nodoc:
|
58
|
+
attrs = []
|
59
|
+
unless attributes.null?
|
60
|
+
j = 0
|
61
|
+
while ! (value = attributes.get_pointer(LibXML.pointer_offset(j))).null?
|
62
|
+
attrs << value.read_string
|
63
|
+
j += 1
|
64
|
+
end
|
65
|
+
end
|
66
|
+
@document.start_element name, attrs
|
67
|
+
end
|
68
|
+
|
69
|
+
def __internal__endElement(_, name) # :nodoc:
|
70
|
+
@document.end_element name
|
71
|
+
end
|
72
|
+
|
73
|
+
def __internal__characters(_, data, data_length) # :nodoc:
|
74
|
+
@document.characters data.slice(0, data_length)
|
75
|
+
end
|
76
|
+
|
77
|
+
def __internal__comment(_, data) # :nodoc:
|
78
|
+
@document.comment data
|
79
|
+
end
|
80
|
+
|
81
|
+
def __internal__warning(_, msg) # :nodoc:
|
82
|
+
# TODO: vasprintf here
|
83
|
+
@document.warning(msg)
|
84
|
+
end
|
85
|
+
|
86
|
+
def __internal__error(_, msg) # :nodoc:
|
87
|
+
# TODO: vasprintf here
|
88
|
+
@document.error(msg)
|
89
|
+
end
|
90
|
+
|
91
|
+
def __internal__cdataBlock(_, data, data_length) # :nodoc:
|
92
|
+
@document.cdata_block data.slice(0, data_length)
|
93
|
+
end
|
94
|
+
|
95
|
+
def __internal__startElementNs(_, localname, prefix, uri, nb_namespaces, namespaces, nb_attributes, nb_defaulted, attributes) # :nodoc:
|
96
|
+
localname = localname.null? ? nil : localname.read_string
|
97
|
+
prefix = prefix .null? ? nil : prefix .read_string
|
98
|
+
uri = uri .null? ? nil : uri .read_string
|
99
|
+
|
100
|
+
attr_hash = {}
|
101
|
+
ns_hash = {}
|
102
|
+
|
103
|
+
if ! attributes.null?
|
104
|
+
# Each attribute is an array of [localname, prefix, URI, value, end]
|
105
|
+
(0..(nb_attributes-1)*5).step(5) do |j|
|
106
|
+
key = attributes.get_pointer(LibXML.pointer_offset(j)).read_string
|
107
|
+
value_length = attributes.get_pointer(LibXML.pointer_offset(j+4)).address \
|
108
|
+
- attributes.get_pointer(LibXML.pointer_offset(j+3)).address
|
109
|
+
value = attributes.get_pointer(LibXML.pointer_offset(j+3)).get_string(0, value_length)
|
110
|
+
attr_hash[key] = value
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
if ! namespaces.null?
|
115
|
+
(0..(nb_namespaces-1)*2).step(2) do |j|
|
116
|
+
key = namespaces.get_pointer(LibXML.pointer_offset(j))
|
117
|
+
key = key.null? ? nil : key.read_string
|
118
|
+
value = namespaces.get_pointer(LibXML.pointer_offset(j+1))
|
119
|
+
value = value.null? ? nil : value.read_string
|
120
|
+
ns_hash[key] = value
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
@document.start_element_ns(localname, attr_hash, prefix, uri, ns_hash)
|
125
|
+
|
126
|
+
if @document.respond_to?(:start_element)
|
127
|
+
name = prefix ? "#{prefix}:#{localname}" : localname
|
128
|
+
@document.start_element(name, attr_hash.to_a.flatten)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
def __internal__endElementNs(_, localname, prefix, uri) # :nodoc:
|
133
|
+
localname = localname.null? ? nil : localname.read_string
|
134
|
+
prefix = prefix .null? ? nil : prefix .read_string
|
135
|
+
uri = uri .null? ? nil : uri .read_string
|
136
|
+
|
137
|
+
@document.end_element_ns(localname, prefix, uri)
|
138
|
+
|
139
|
+
if @document.respond_to?(:end_element)
|
140
|
+
name = prefix ? "#{prefix}:#{localname}" : localname
|
141
|
+
@document.end_element(name)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Nokogiri
|
2
|
+
module XML
|
3
|
+
module SAX
|
4
|
+
class PushParser
|
5
|
+
|
6
|
+
attr_accessor :cstruct # :nodoc:
|
7
|
+
|
8
|
+
private
|
9
|
+
|
10
|
+
def native_write(chunk, last_chunk) # :nodoc:
|
11
|
+
size = 0
|
12
|
+
unless chunk.nil?
|
13
|
+
chunk = chunk.to_s
|
14
|
+
size = chunk.length
|
15
|
+
end
|
16
|
+
|
17
|
+
last_chunk = last_chunk ? 1 : 0
|
18
|
+
|
19
|
+
rcode = LibXML.xmlParseChunk(cstruct, chunk, size, last_chunk)
|
20
|
+
raise RuntimeError, "Couldn't parse chunk" if 0 != rcode
|
21
|
+
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize_native(sax, filename) # :nodoc:
|
26
|
+
filename = filename.to_s unless filename.nil?
|
27
|
+
ctx_ptr = LibXML.xmlCreatePushParserCtxt(
|
28
|
+
sax.cstruct, nil, nil, 0, filename
|
29
|
+
)
|
30
|
+
raise(RuntimeError, "Could not create a parser context") if ctx_ptr.null?
|
31
|
+
self.cstruct = LibXML::XmlSaxPushParserContext.new(ctx_ptr) ;
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|