nokogiri 1.11.0.rc3-java → 1.11.4-java
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.
- checksums.yaml +4 -4
- data/Gemfile +3 -0
- data/LICENSE-DEPENDENCIES.md +1015 -947
- data/LICENSE.md +1 -1
- data/README.md +168 -91
- data/dependencies.yml +12 -12
- data/ext/java/nokogiri/EncodingHandler.java +76 -89
- data/ext/java/nokogiri/HtmlDocument.java +135 -144
- data/ext/java/nokogiri/HtmlElementDescription.java +102 -117
- data/ext/java/nokogiri/HtmlEntityLookup.java +33 -60
- data/ext/java/nokogiri/HtmlSaxParserContext.java +218 -222
- data/ext/java/nokogiri/HtmlSaxPushParser.java +162 -169
- data/ext/java/nokogiri/NokogiriService.java +595 -556
- data/ext/java/nokogiri/XmlAttr.java +118 -126
- data/ext/java/nokogiri/XmlAttributeDecl.java +95 -106
- data/ext/java/nokogiri/XmlCdata.java +35 -58
- data/ext/java/nokogiri/XmlComment.java +46 -67
- data/ext/java/nokogiri/XmlDocument.java +645 -572
- data/ext/java/nokogiri/XmlDocumentFragment.java +125 -137
- data/ext/java/nokogiri/XmlDtd.java +448 -414
- data/ext/java/nokogiri/XmlElement.java +23 -48
- data/ext/java/nokogiri/XmlElementContent.java +343 -316
- data/ext/java/nokogiri/XmlElementDecl.java +124 -125
- data/ext/java/nokogiri/XmlEntityDecl.java +119 -127
- data/ext/java/nokogiri/XmlEntityReference.java +49 -72
- data/ext/java/nokogiri/XmlNamespace.java +175 -175
- data/ext/java/nokogiri/XmlNode.java +1843 -1622
- data/ext/java/nokogiri/XmlNodeSet.java +361 -331
- data/ext/java/nokogiri/XmlProcessingInstruction.java +47 -69
- data/ext/java/nokogiri/XmlReader.java +513 -450
- data/ext/java/nokogiri/XmlRelaxng.java +89 -101
- data/ext/java/nokogiri/XmlSaxParserContext.java +328 -310
- data/ext/java/nokogiri/XmlSaxPushParser.java +227 -220
- data/ext/java/nokogiri/XmlSchema.java +335 -242
- data/ext/java/nokogiri/XmlSyntaxError.java +113 -119
- data/ext/java/nokogiri/XmlText.java +55 -76
- data/ext/java/nokogiri/XmlXpathContext.java +242 -210
- data/ext/java/nokogiri/XsltStylesheet.java +280 -269
- data/ext/java/nokogiri/internals/ClosedStreamException.java +5 -2
- data/ext/java/nokogiri/internals/HtmlDomParserContext.java +201 -190
- data/ext/java/nokogiri/internals/IgnoreSchemaErrorsErrorHandler.java +17 -10
- data/ext/java/nokogiri/internals/NokogiriBlockingQueueInputStream.java +43 -16
- data/ext/java/nokogiri/internals/NokogiriDomParser.java +63 -80
- data/ext/java/nokogiri/internals/NokogiriEntityResolver.java +107 -88
- data/ext/java/nokogiri/internals/NokogiriErrorHandler.java +27 -52
- data/ext/java/nokogiri/internals/NokogiriHandler.java +316 -286
- data/ext/java/nokogiri/internals/NokogiriHelpers.java +736 -652
- data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +184 -173
- data/ext/java/nokogiri/internals/NokogiriNamespaceContext.java +79 -89
- data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler.java +64 -79
- data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler4NekoHtml.java +84 -99
- data/ext/java/nokogiri/internals/NokogiriStrictErrorHandler.java +48 -65
- data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +119 -78
- data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +34 -54
- data/ext/java/nokogiri/internals/NokogiriXPathVariableResolver.java +23 -46
- data/ext/java/nokogiri/internals/NokogiriXsltErrorListener.java +55 -72
- data/ext/java/nokogiri/internals/ParserContext.java +206 -211
- data/ext/java/nokogiri/internals/ReaderNode.java +478 -403
- data/ext/java/nokogiri/internals/SaveContextVisitor.java +822 -739
- data/ext/java/nokogiri/internals/SchemaErrorHandler.java +31 -54
- data/ext/java/nokogiri/internals/XalanDTMManagerPatch.java +129 -123
- data/ext/java/nokogiri/internals/XmlDeclHandler.java +3 -34
- data/ext/java/nokogiri/internals/XmlDomParserContext.java +206 -207
- data/ext/java/nokogiri/internals/XmlSaxParser.java +22 -47
- data/ext/java/nokogiri/internals/c14n/AttrCompare.java +71 -68
- data/ext/java/nokogiri/internals/c14n/C14nHelper.java +137 -118
- data/ext/java/nokogiri/internals/c14n/CanonicalFilter.java +27 -21
- data/ext/java/nokogiri/internals/c14n/CanonicalizationException.java +74 -61
- data/ext/java/nokogiri/internals/c14n/Canonicalizer.java +230 -205
- data/ext/java/nokogiri/internals/c14n/Canonicalizer11.java +572 -547
- data/ext/java/nokogiri/internals/c14n/Canonicalizer11_OmitComments.java +17 -10
- data/ext/java/nokogiri/internals/c14n/Canonicalizer11_WithComments.java +17 -10
- data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315.java +323 -302
- data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315Excl.java +232 -219
- data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315ExclOmitComments.java +22 -15
- data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315ExclWithComments.java +23 -16
- data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315OmitComments.java +23 -16
- data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315WithComments.java +22 -15
- data/ext/java/nokogiri/internals/c14n/CanonicalizerBase.java +575 -545
- data/ext/java/nokogiri/internals/c14n/CanonicalizerPhysical.java +141 -120
- data/ext/java/nokogiri/internals/c14n/CanonicalizerSpi.java +39 -38
- data/ext/java/nokogiri/internals/c14n/Constants.java +13 -10
- data/ext/java/nokogiri/internals/c14n/ElementProxy.java +279 -247
- data/ext/java/nokogiri/internals/c14n/HelperNodeList.java +66 -53
- data/ext/java/nokogiri/internals/c14n/IgnoreAllErrorHandler.java +44 -37
- data/ext/java/nokogiri/internals/c14n/InclusiveNamespaces.java +135 -120
- data/ext/java/nokogiri/internals/c14n/InvalidCanonicalizerException.java +59 -48
- data/ext/java/nokogiri/internals/c14n/NameSpaceSymbTable.java +384 -334
- data/ext/java/nokogiri/internals/c14n/NodeFilter.java +25 -24
- data/ext/java/nokogiri/internals/c14n/UtfHelpper.java +151 -140
- data/ext/java/nokogiri/internals/c14n/XMLUtils.java +456 -423
- data/ext/java/nokogiri/internals/dom2dtm/DOM2DTM.java +1466 -1500
- data/ext/java/nokogiri/internals/dom2dtm/DOM2DTMdefaultNamespaceDeclarationNode.java +626 -574
- data/ext/nokogiri/depend +37 -358
- data/ext/nokogiri/extconf.rb +581 -374
- data/ext/nokogiri/html_document.c +78 -82
- data/ext/nokogiri/html_element_description.c +84 -71
- data/ext/nokogiri/html_entity_lookup.c +21 -16
- data/ext/nokogiri/html_sax_parser_context.c +69 -66
- data/ext/nokogiri/html_sax_push_parser.c +42 -34
- data/ext/nokogiri/libxml2_backwards_compat.c +121 -0
- data/ext/nokogiri/nokogiri.c +192 -93
- data/ext/nokogiri/test_global_handlers.c +40 -0
- data/ext/nokogiri/xml_attr.c +15 -15
- data/ext/nokogiri/xml_attribute_decl.c +18 -18
- data/ext/nokogiri/xml_cdata.c +13 -18
- data/ext/nokogiri/xml_comment.c +19 -26
- data/ext/nokogiri/xml_document.c +246 -188
- data/ext/nokogiri/xml_document_fragment.c +13 -15
- data/ext/nokogiri/xml_dtd.c +54 -48
- data/ext/nokogiri/xml_element_content.c +30 -27
- data/ext/nokogiri/xml_element_decl.c +22 -22
- data/ext/nokogiri/xml_encoding_handler.c +17 -11
- data/ext/nokogiri/xml_entity_decl.c +32 -30
- data/ext/nokogiri/xml_entity_reference.c +16 -18
- data/ext/nokogiri/xml_namespace.c +56 -49
- data/ext/nokogiri/xml_node.c +371 -320
- data/ext/nokogiri/xml_node_set.c +168 -156
- data/ext/nokogiri/xml_processing_instruction.c +17 -19
- data/ext/nokogiri/xml_reader.c +191 -157
- data/ext/nokogiri/xml_relax_ng.c +52 -28
- data/ext/nokogiri/xml_sax_parser.c +118 -118
- data/ext/nokogiri/xml_sax_parser_context.c +103 -86
- data/ext/nokogiri/xml_sax_push_parser.c +36 -27
- data/ext/nokogiri/xml_schema.c +95 -47
- data/ext/nokogiri/xml_syntax_error.c +42 -21
- data/ext/nokogiri/xml_text.c +13 -17
- data/ext/nokogiri/xml_xpath_context.c +206 -123
- data/ext/nokogiri/xslt_stylesheet.c +158 -161
- data/lib/nokogiri.rb +3 -7
- data/lib/nokogiri/css/parser.rb +3 -3
- data/lib/nokogiri/css/parser.y +2 -2
- data/lib/nokogiri/css/xpath_visitor.rb +70 -42
- data/lib/nokogiri/extension.rb +26 -0
- data/lib/nokogiri/html/document.rb +12 -26
- data/lib/nokogiri/html/document_fragment.rb +15 -15
- data/lib/nokogiri/nokogiri.jar +0 -0
- data/lib/nokogiri/version.rb +2 -149
- data/lib/nokogiri/version/constant.rb +5 -0
- data/lib/nokogiri/version/info.rb +205 -0
- data/lib/nokogiri/xml/document.rb +91 -35
- data/lib/nokogiri/xml/document_fragment.rb +4 -6
- data/lib/nokogiri/xml/node.rb +89 -69
- data/lib/nokogiri/xml/parse_options.rb +6 -0
- data/lib/nokogiri/xml/reader.rb +2 -9
- data/lib/nokogiri/xml/relax_ng.rb +6 -2
- data/lib/nokogiri/xml/schema.rb +12 -4
- data/lib/nokogiri/xml/searchable.rb +3 -1
- data/lib/nokogiri/xml/xpath.rb +1 -3
- data/lib/nokogiri/xml/xpath/syntax_error.rb +1 -1
- metadata +86 -177
- data/ext/nokogiri/html_document.h +0 -10
- data/ext/nokogiri/html_element_description.h +0 -10
- data/ext/nokogiri/html_entity_lookup.h +0 -8
- data/ext/nokogiri/html_sax_parser_context.h +0 -11
- data/ext/nokogiri/html_sax_push_parser.h +0 -9
- data/ext/nokogiri/nokogiri.h +0 -134
- data/ext/nokogiri/xml_attr.h +0 -9
- data/ext/nokogiri/xml_attribute_decl.h +0 -9
- data/ext/nokogiri/xml_cdata.h +0 -9
- data/ext/nokogiri/xml_comment.h +0 -9
- data/ext/nokogiri/xml_document.h +0 -23
- data/ext/nokogiri/xml_document_fragment.h +0 -10
- data/ext/nokogiri/xml_dtd.h +0 -10
- data/ext/nokogiri/xml_element_content.h +0 -10
- data/ext/nokogiri/xml_element_decl.h +0 -9
- data/ext/nokogiri/xml_encoding_handler.h +0 -8
- data/ext/nokogiri/xml_entity_decl.h +0 -10
- data/ext/nokogiri/xml_entity_reference.h +0 -9
- data/ext/nokogiri/xml_io.c +0 -63
- data/ext/nokogiri/xml_io.h +0 -11
- data/ext/nokogiri/xml_libxml2_hacks.c +0 -112
- data/ext/nokogiri/xml_libxml2_hacks.h +0 -12
- data/ext/nokogiri/xml_namespace.h +0 -14
- data/ext/nokogiri/xml_node.h +0 -13
- data/ext/nokogiri/xml_node_set.h +0 -12
- data/ext/nokogiri/xml_processing_instruction.h +0 -9
- data/ext/nokogiri/xml_reader.h +0 -10
- data/ext/nokogiri/xml_relax_ng.h +0 -9
- data/ext/nokogiri/xml_sax_parser.h +0 -39
- data/ext/nokogiri/xml_sax_parser_context.h +0 -10
- data/ext/nokogiri/xml_sax_push_parser.h +0 -9
- data/ext/nokogiri/xml_schema.h +0 -9
- data/ext/nokogiri/xml_syntax_error.h +0 -13
- data/ext/nokogiri/xml_text.h +0 -9
- data/ext/nokogiri/xml_xpath_context.h +0 -10
- data/ext/nokogiri/xslt_stylesheet.h +0 -14
@@ -1,35 +1,3 @@
|
|
1
|
-
/**
|
2
|
-
* (The MIT License)
|
3
|
-
*
|
4
|
-
* Copyright (c) 2008 - 2012:
|
5
|
-
*
|
6
|
-
* * {Aaron Patterson}[http://tenderlovemaking.com]
|
7
|
-
* * {Mike Dalessio}[http://mike.daless.io]
|
8
|
-
* * {Charles Nutter}[http://blog.headius.com]
|
9
|
-
* * {Sergio Arbeo}[http://www.serabe.com]
|
10
|
-
* * {Patrick Mahoney}[http://polycrystal.org]
|
11
|
-
* * {Yoko Harada}[http://yokolet.blogspot.com]
|
12
|
-
*
|
13
|
-
* Permission is hereby granted, free of charge, to any person obtaining
|
14
|
-
* a copy of this software and associated documentation files (the
|
15
|
-
* 'Software'), to deal in the Software without restriction, including
|
16
|
-
* without limitation the rights to use, copy, modify, merge, publish,
|
17
|
-
* distribute, sublicense, and/or sell copies of the Software, and to
|
18
|
-
* permit persons to whom the Software is furnished to do so, subject to
|
19
|
-
* the following conditions:
|
20
|
-
*
|
21
|
-
* The above copyright notice and this permission notice shall be
|
22
|
-
* included in all copies or substantial portions of the Software.
|
23
|
-
*
|
24
|
-
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
25
|
-
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
26
|
-
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
27
|
-
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
28
|
-
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
29
|
-
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
30
|
-
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
31
|
-
*/
|
32
|
-
|
33
1
|
package nokogiri.internals;
|
34
2
|
|
35
3
|
import static nokogiri.internals.NokogiriHelpers.rubyStringToString;
|
@@ -58,202 +26,229 @@ import org.xml.sax.InputSource;
|
|
58
26
|
* @author Patrick Mahoney <pat@polycrystal.org>
|
59
27
|
* @author Yoko Harada <yokolet@gmail.com>
|
60
28
|
*/
|
61
|
-
public abstract class ParserContext extends RubyObject
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
29
|
+
public abstract class ParserContext extends RubyObject
|
30
|
+
{
|
31
|
+
protected InputSource source = null;
|
32
|
+
protected IRubyObject detected_encoding = null;
|
33
|
+
protected int stringDataSize = -1;
|
34
|
+
protected String java_encoding;
|
35
|
+
|
36
|
+
public
|
37
|
+
ParserContext(Ruby runtime)
|
38
|
+
{
|
39
|
+
// default to class 'Object' because this class isn't exposed to Ruby
|
40
|
+
super(runtime, runtime.getObject());
|
41
|
+
}
|
42
|
+
|
43
|
+
public
|
44
|
+
ParserContext(Ruby runtime, RubyClass klass)
|
45
|
+
{
|
46
|
+
super(runtime, klass);
|
47
|
+
}
|
48
|
+
|
49
|
+
protected InputSource
|
50
|
+
getInputSource()
|
51
|
+
{
|
52
|
+
return source;
|
53
|
+
}
|
54
|
+
|
55
|
+
public void
|
56
|
+
setIOInputSource(ThreadContext context, IRubyObject data, IRubyObject url)
|
57
|
+
{
|
58
|
+
source = new InputSource();
|
59
|
+
ParserContext.setUrl(context, source, url);
|
60
|
+
|
61
|
+
source.setByteStream(new IOInputStream(data));
|
62
|
+
if (java_encoding != null) {
|
63
|
+
source.setEncoding(java_encoding);
|
70
64
|
}
|
65
|
+
}
|
71
66
|
|
72
|
-
|
73
|
-
|
74
|
-
|
67
|
+
public void
|
68
|
+
setStringInputSource(ThreadContext context, IRubyObject data, IRubyObject url)
|
69
|
+
{
|
70
|
+
source = new InputSource();
|
71
|
+
ParserContext.setUrl(context, source, url);
|
75
72
|
|
76
|
-
|
77
|
-
return source;
|
78
|
-
}
|
79
|
-
|
80
|
-
public void setIOInputSource(ThreadContext context, IRubyObject data, IRubyObject url) {
|
81
|
-
source = new InputSource();
|
82
|
-
ParserContext.setUrl(context, source, url);
|
73
|
+
Ruby ruby = context.getRuntime();
|
83
74
|
|
84
|
-
|
85
|
-
|
86
|
-
source.setEncoding(java_encoding);
|
87
|
-
}
|
75
|
+
if (!(data instanceof RubyString)) {
|
76
|
+
throw ruby.newArgumentError("must be kind_of String");
|
88
77
|
}
|
89
78
|
|
90
|
-
|
91
|
-
source = new InputSource();
|
92
|
-
ParserContext.setUrl(context, source, url);
|
93
|
-
|
94
|
-
Ruby ruby = context.getRuntime();
|
95
|
-
|
96
|
-
if (!(data instanceof RubyString)) {
|
97
|
-
throw ruby.newArgumentError("must be kind_of String");
|
98
|
-
}
|
99
|
-
|
100
|
-
RubyString stringData = (RubyString) data;
|
101
|
-
|
102
|
-
if (stringData.encoding(context) != null) {
|
103
|
-
RubyString stringEncoding = stringData.encoding(context).asString();
|
104
|
-
String encName = NokogiriHelpers.getValidEncodingOrNull(stringEncoding);
|
105
|
-
if (encName != null) {
|
106
|
-
java_encoding = encName;
|
107
|
-
}
|
108
|
-
}
|
109
|
-
|
110
|
-
ByteList bytes = stringData.getByteList();
|
79
|
+
RubyString stringData = (RubyString) data;
|
111
80
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
81
|
+
if (stringData.encoding(context) != null) {
|
82
|
+
RubyString stringEncoding = stringData.encoding(context).asString();
|
83
|
+
String encName = NokogiriHelpers.getValidEncodingOrNull(stringEncoding);
|
84
|
+
if (encName != null) {
|
85
|
+
java_encoding = encName;
|
86
|
+
}
|
116
87
|
}
|
117
88
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
89
|
+
ByteList bytes = stringData.getByteList();
|
90
|
+
|
91
|
+
stringDataSize = bytes.length() - bytes.begin();
|
92
|
+
ByteArrayInputStream stream = new ByteArrayInputStream(bytes.unsafeBytes(), bytes.begin(), bytes.length());
|
93
|
+
source.setByteStream(stream);
|
94
|
+
source.setEncoding(java_encoding);
|
95
|
+
}
|
96
|
+
|
97
|
+
public static void
|
98
|
+
setUrl(ThreadContext context, InputSource source, IRubyObject url)
|
99
|
+
{
|
100
|
+
String path = rubyStringToString(url);
|
101
|
+
// Dir.chdir might be called at some point before this.
|
102
|
+
if (path != null) {
|
103
|
+
try {
|
104
|
+
URI uri = URI.create(path);
|
105
|
+
source.setSystemId(uri.toURL().toString());
|
106
|
+
} catch (Exception ex) {
|
107
|
+
// fallback to the old behavior
|
108
|
+
File file = new File(path);
|
109
|
+
if (file.isAbsolute()) {
|
110
|
+
source.setSystemId(path);
|
111
|
+
} else {
|
112
|
+
String pwd = context.getRuntime().getCurrentDirectory();
|
113
|
+
String absolutePath;
|
122
114
|
try {
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
// fallback to the old behavior
|
127
|
-
File file = new File(path);
|
128
|
-
if (file.isAbsolute()) {
|
129
|
-
source.setSystemId(path);
|
130
|
-
} else {
|
131
|
-
String pwd = context.getRuntime().getCurrentDirectory();
|
132
|
-
String absolutePath;
|
133
|
-
try {
|
134
|
-
absolutePath = new File(pwd, path).getCanonicalPath();
|
135
|
-
} catch (IOException e) {
|
136
|
-
absolutePath = new File(pwd, path).getAbsolutePath();
|
137
|
-
}
|
138
|
-
source.setSystemId(absolutePath);
|
139
|
-
}
|
115
|
+
absolutePath = new File(pwd, path).getCanonicalPath();
|
116
|
+
} catch (IOException e) {
|
117
|
+
absolutePath = new File(pwd, path).getAbsolutePath();
|
140
118
|
}
|
119
|
+
source.setSystemId(absolutePath);
|
141
120
|
}
|
121
|
+
}
|
142
122
|
}
|
143
|
-
|
144
|
-
|
145
|
-
|
123
|
+
}
|
124
|
+
|
125
|
+
protected void
|
126
|
+
setEncoding(String encoding)
|
127
|
+
{
|
128
|
+
source.setEncoding(encoding);
|
129
|
+
}
|
130
|
+
|
131
|
+
/**
|
132
|
+
* Set the InputSource to read from <code>file</code>, a String filename.
|
133
|
+
*/
|
134
|
+
public void
|
135
|
+
setInputSourceFile(ThreadContext context, IRubyObject file)
|
136
|
+
{
|
137
|
+
source = new InputSource();
|
138
|
+
ParserContext.setUrl(context, source, file);
|
139
|
+
}
|
140
|
+
|
141
|
+
/**
|
142
|
+
* Set the InputSource from <code>stream</code>.
|
143
|
+
*/
|
144
|
+
public void
|
145
|
+
setInputSource(InputStream stream)
|
146
|
+
{
|
147
|
+
source = new InputSource(stream);
|
148
|
+
}
|
149
|
+
|
150
|
+
/**
|
151
|
+
* Wrap Nokogiri parser options in a utility class. This is
|
152
|
+
* read-only.
|
153
|
+
*/
|
154
|
+
public static class Options
|
155
|
+
{
|
156
|
+
protected static final long STRICT = 0;
|
157
|
+
protected static final long RECOVER = 1;
|
158
|
+
protected static final long NOENT = 2;
|
159
|
+
protected static final long DTDLOAD = 4;
|
160
|
+
protected static final long DTDATTR = 8;
|
161
|
+
protected static final long DTDVALID = 16;
|
162
|
+
protected static final long NOERROR = 32;
|
163
|
+
protected static final long NOWARNING = 64;
|
164
|
+
protected static final long PEDANTIC = 128;
|
165
|
+
protected static final long NOBLANKS = 256;
|
166
|
+
protected static final long SAX1 = 512;
|
167
|
+
protected static final long XINCLUDE = 1024;
|
168
|
+
protected static final long NONET = 2048;
|
169
|
+
protected static final long NODICT = 4096;
|
170
|
+
protected static final long NSCLEAN = 8192;
|
171
|
+
protected static final long NOCDATA = 16384;
|
172
|
+
protected static final long NOXINCNODE = 32768;
|
173
|
+
|
174
|
+
public final boolean strict;
|
175
|
+
public final boolean recover;
|
176
|
+
public final boolean noEnt;
|
177
|
+
public final boolean dtdLoad;
|
178
|
+
public final boolean dtdAttr;
|
179
|
+
public final boolean dtdValid;
|
180
|
+
public final boolean noError;
|
181
|
+
public final boolean noWarning;
|
182
|
+
public final boolean pedantic;
|
183
|
+
public final boolean noBlanks;
|
184
|
+
public final boolean sax1;
|
185
|
+
public final boolean xInclude;
|
186
|
+
public final boolean noNet;
|
187
|
+
public final boolean noDict;
|
188
|
+
public final boolean nsClean;
|
189
|
+
public final boolean noCdata;
|
190
|
+
public final boolean noXIncNode;
|
191
|
+
|
192
|
+
protected static boolean
|
193
|
+
test(long options, long mask)
|
194
|
+
{
|
195
|
+
return ((options & mask) == mask);
|
146
196
|
}
|
147
197
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
198
|
+
public
|
199
|
+
Options(long options)
|
200
|
+
{
|
201
|
+
strict = ((options & RECOVER) == STRICT);
|
202
|
+
recover = test(options, RECOVER);
|
203
|
+
noEnt = test(options, NOENT);
|
204
|
+
dtdLoad = test(options, DTDLOAD);
|
205
|
+
dtdAttr = test(options, DTDATTR);
|
206
|
+
dtdValid = test(options, DTDVALID);
|
207
|
+
noError = test(options, NOERROR);
|
208
|
+
noWarning = test(options, NOWARNING);
|
209
|
+
pedantic = test(options, PEDANTIC);
|
210
|
+
noBlanks = test(options, NOBLANKS);
|
211
|
+
sax1 = test(options, SAX1);
|
212
|
+
xInclude = test(options, XINCLUDE);
|
213
|
+
noNet = test(options, NONET);
|
214
|
+
noDict = test(options, NODICT);
|
215
|
+
nsClean = test(options, NSCLEAN);
|
216
|
+
noCdata = test(options, NOCDATA);
|
217
|
+
noXIncNode = test(options, NOXINCNODE);
|
154
218
|
}
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
public final boolean strict;
|
187
|
-
public final boolean recover;
|
188
|
-
public final boolean noEnt;
|
189
|
-
public final boolean dtdLoad;
|
190
|
-
public final boolean dtdAttr;
|
191
|
-
public final boolean dtdValid;
|
192
|
-
public final boolean noError;
|
193
|
-
public final boolean noWarning;
|
194
|
-
public final boolean pedantic;
|
195
|
-
public final boolean noBlanks;
|
196
|
-
public final boolean sax1;
|
197
|
-
public final boolean xInclude;
|
198
|
-
public final boolean noNet;
|
199
|
-
public final boolean noDict;
|
200
|
-
public final boolean nsClean;
|
201
|
-
public final boolean noCdata;
|
202
|
-
public final boolean noXIncNode;
|
203
|
-
|
204
|
-
protected static boolean test(long options, long mask) {
|
205
|
-
return ((options & mask) == mask);
|
206
|
-
}
|
207
|
-
|
208
|
-
public Options(long options) {
|
209
|
-
strict = ((options & RECOVER) == STRICT);
|
210
|
-
recover = test(options, RECOVER);
|
211
|
-
noEnt = test(options, NOENT);
|
212
|
-
dtdLoad = test(options, DTDLOAD);
|
213
|
-
dtdAttr = test(options, DTDATTR);
|
214
|
-
dtdValid = test(options, DTDVALID);
|
215
|
-
noError = test(options, NOERROR);
|
216
|
-
noWarning = test(options, NOWARNING);
|
217
|
-
pedantic = test(options, PEDANTIC);
|
218
|
-
noBlanks = test(options, NOBLANKS);
|
219
|
-
sax1 = test(options, SAX1);
|
220
|
-
xInclude = test(options, XINCLUDE);
|
221
|
-
noNet = test(options, NONET);
|
222
|
-
noDict = test(options, NODICT);
|
223
|
-
nsClean = test(options, NSCLEAN);
|
224
|
-
noCdata = test(options, NOCDATA);
|
225
|
-
noXIncNode = test(options, NOXINCNODE);
|
226
|
-
}
|
219
|
+
}
|
220
|
+
|
221
|
+
/*
|
222
|
+
public static class NokogiriXInlcudeEntityResolver implements org.xml.sax.EntityResolver {
|
223
|
+
InputSource source;
|
224
|
+
public NokogiriXInlcudeEntityResolver(InputSource source) {
|
225
|
+
this.source = source;
|
226
|
+
}
|
227
|
+
|
228
|
+
@Override
|
229
|
+
public InputSource resolveEntity(String publicId, String systemId)
|
230
|
+
throws SAXException, IOException {
|
231
|
+
if (systemId != null) source.setSystemId(systemId);
|
232
|
+
if (publicId != null) source.setPublicId(publicId);
|
233
|
+
return source;
|
234
|
+
}
|
235
|
+
} */
|
236
|
+
|
237
|
+
public static abstract class ParserTask<T extends ParserContext> implements Callable<T>
|
238
|
+
{
|
239
|
+
|
240
|
+
protected final ThreadContext context; // TODO does not seem like a good idea!?
|
241
|
+
protected final IRubyObject handler;
|
242
|
+
protected final T parser;
|
243
|
+
|
244
|
+
protected
|
245
|
+
ParserTask(ThreadContext context, IRubyObject handler, T parser)
|
246
|
+
{
|
247
|
+
this.context = context;
|
248
|
+
this.handler = handler;
|
249
|
+
this.parser = parser;
|
227
250
|
}
|
228
251
|
|
229
|
-
|
230
|
-
public static class NokogiriXInlcudeEntityResolver implements org.xml.sax.EntityResolver {
|
231
|
-
InputSource source;
|
232
|
-
public NokogiriXInlcudeEntityResolver(InputSource source) {
|
233
|
-
this.source = source;
|
234
|
-
}
|
235
|
-
|
236
|
-
@Override
|
237
|
-
public InputSource resolveEntity(String publicId, String systemId)
|
238
|
-
throws SAXException, IOException {
|
239
|
-
if (systemId != null) source.setSystemId(systemId);
|
240
|
-
if (publicId != null) source.setPublicId(publicId);
|
241
|
-
return source;
|
242
|
-
}
|
243
|
-
} */
|
244
|
-
|
245
|
-
public static abstract class ParserTask<T extends ParserContext> implements Callable<T> {
|
246
|
-
|
247
|
-
protected final ThreadContext context; // TODO does not seem like a good idea!?
|
248
|
-
protected final IRubyObject handler;
|
249
|
-
protected final T parser;
|
250
|
-
|
251
|
-
protected ParserTask(ThreadContext context, IRubyObject handler, T parser) {
|
252
|
-
this.context = context;
|
253
|
-
this.handler = handler;
|
254
|
-
this.parser = parser;
|
255
|
-
}
|
256
|
-
|
257
|
-
}
|
252
|
+
}
|
258
253
|
|
259
254
|
}
|
@@ -1,35 +1,3 @@
|
|
1
|
-
/**
|
2
|
-
* (The MIT License)
|
3
|
-
*
|
4
|
-
* Copyright (c) 2008 - 2011:
|
5
|
-
*
|
6
|
-
* * {Aaron Patterson}[http://tenderlovemaking.com]
|
7
|
-
* * {Mike Dalessio}[http://mike.daless.io]
|
8
|
-
* * {Charles Nutter}[http://blog.headius.com]
|
9
|
-
* * {Sergio Arbeo}[http://www.serabe.com]
|
10
|
-
* * {Patrick Mahoney}[http://polycrystal.org]
|
11
|
-
* * {Yoko Harada}[http://yokolet.blogspot.com]
|
12
|
-
*
|
13
|
-
* Permission is hereby granted, free of charge, to any person obtaining
|
14
|
-
* a copy of this software and associated documentation files (the
|
15
|
-
* 'Software'), to deal in the Software without restriction, including
|
16
|
-
* without limitation the rights to use, copy, modify, merge, publish,
|
17
|
-
* distribute, sublicense, and/or sell copies of the Software, and to
|
18
|
-
* permit persons to whom the Software is furnished to do so, subject to
|
19
|
-
* the following conditions:
|
20
|
-
*
|
21
|
-
* The above copyright notice and this permission notice shall be
|
22
|
-
* included in all copies or substantial portions of the Software.
|
23
|
-
*
|
24
|
-
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
25
|
-
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
26
|
-
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
27
|
-
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
28
|
-
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
29
|
-
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
30
|
-
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
31
|
-
*/
|
32
|
-
|
33
1
|
package nokogiri.internals;
|
34
2
|
|
35
3
|
import java.util.ArrayList;
|
@@ -62,427 +30,534 @@ import static nokogiri.internals.NokogiriHelpers.*;
|
|
62
30
|
* @author Yoko Harada <yokolet@gmail.com>
|
63
31
|
*
|
64
32
|
*/
|
65
|
-
public abstract class ReaderNode
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
33
|
+
public abstract class ReaderNode
|
34
|
+
{
|
35
|
+
|
36
|
+
final Ruby ruby;
|
37
|
+
public ReaderAttributeList attributeList;
|
38
|
+
public Map<String, String> namespaces;
|
39
|
+
public int depth, nodeType;
|
40
|
+
public String lang, localName, xmlBase, prefix, name, uri, value, xmlVersion = "1.0";
|
41
|
+
public int startOffset, endOffset;
|
42
|
+
public boolean hasChildren = false;
|
43
|
+
private Document document = null;
|
44
|
+
|
45
|
+
protected
|
46
|
+
ReaderNode(final Ruby runtime)
|
47
|
+
{
|
48
|
+
this.ruby = runtime;
|
49
|
+
}
|
50
|
+
|
51
|
+
public abstract String getString();
|
52
|
+
|
53
|
+
public IRubyObject
|
54
|
+
getAttributeByIndex(IRubyObject index)
|
55
|
+
{
|
56
|
+
if (index.isNil()) { return index; }
|
57
|
+
|
58
|
+
long i = index.convertToInteger().getLongValue();
|
59
|
+
if (i > Integer.MAX_VALUE) {
|
60
|
+
throw ruby.newArgumentError("value too long to be an array index");
|
78
61
|
}
|
79
62
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
63
|
+
if (attributeList == null) { return ruby.getNil(); }
|
64
|
+
if (i < 0 || attributeList.length <= i) { return ruby.getNil(); }
|
65
|
+
return stringOrBlank(ruby, attributeList.values.get(((Long)i).intValue()));
|
66
|
+
}
|
67
|
+
|
68
|
+
public IRubyObject
|
69
|
+
getAttributeByName(IRubyObject name)
|
70
|
+
{
|
71
|
+
if (attributeList == null) { return ruby.getNil(); }
|
72
|
+
String value = attributeList.getByName(rubyStringToString(name));
|
73
|
+
return stringOrNil(ruby, value);
|
74
|
+
}
|
75
|
+
|
76
|
+
public IRubyObject
|
77
|
+
getAttributeByName(String name)
|
78
|
+
{
|
79
|
+
if (attributeList == null) { return ruby.getNil(); }
|
80
|
+
String value = attributeList.getByName(name);
|
81
|
+
return stringOrNil(ruby, value);
|
82
|
+
}
|
83
|
+
|
84
|
+
public IRubyObject
|
85
|
+
getAttributeCount()
|
86
|
+
{
|
87
|
+
if (attributeList == null) { return ruby.newFixnum(0); }
|
88
|
+
return ruby.newFixnum(attributeList.length);
|
89
|
+
}
|
90
|
+
|
91
|
+
public IRubyObject
|
92
|
+
getAttributesNodes()
|
93
|
+
{
|
94
|
+
RubyArray array = RubyArray.newArray(ruby);
|
95
|
+
if (attributeList != null && attributeList.length > 0) {
|
96
|
+
if (document == null) {
|
97
|
+
document = XmlDocument.createNewDocument(ruby);
|
98
|
+
}
|
99
|
+
for (int i = 0; i < attributeList.length; i++) {
|
100
|
+
if (!isNamespace(attributeList.names.get(i))) {
|
101
|
+
Attr attr = document.createAttributeNS(attributeList.namespaces.get(i), attributeList.names.get(i));
|
102
|
+
attr.setValue(attributeList.values.get(i));
|
103
|
+
XmlAttr xmlAttr = new XmlAttr(ruby, attr);
|
104
|
+
array.append(xmlAttr);
|
88
105
|
}
|
89
|
-
|
90
|
-
if (attributeList == null) return ruby.getNil();
|
91
|
-
if (i<0 || attributeList.length <= i) return ruby.getNil();
|
92
|
-
return stringOrBlank(ruby, attributeList.values.get(((Long)i).intValue()));
|
106
|
+
}
|
93
107
|
}
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
108
|
+
return array;
|
109
|
+
}
|
110
|
+
|
111
|
+
public IRubyObject
|
112
|
+
getAttributes(ThreadContext context)
|
113
|
+
{
|
114
|
+
final Ruby runtime = context.runtime;
|
115
|
+
if (attributeList == null) { return runtime.getNil(); }
|
116
|
+
RubyHash hash = RubyHash.newHash(runtime);
|
117
|
+
for (int i = 0; i < attributeList.length; i++) {
|
118
|
+
IRubyObject k = stringOrBlank(runtime, attributeList.names.get(i));
|
119
|
+
IRubyObject v = stringOrBlank(runtime, attributeList.values.get(i));
|
120
|
+
hash.fastASetCheckString(runtime, k, v); // hash.op_aset(context, k, v)
|
99
121
|
}
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
122
|
+
return hash;
|
123
|
+
}
|
124
|
+
|
125
|
+
public IRubyObject
|
126
|
+
getDepth()
|
127
|
+
{
|
128
|
+
return ruby.newFixnum(depth);
|
129
|
+
}
|
130
|
+
|
131
|
+
public IRubyObject
|
132
|
+
getLang()
|
133
|
+
{
|
134
|
+
return stringOrNil(ruby, lang);
|
135
|
+
}
|
136
|
+
|
137
|
+
public IRubyObject
|
138
|
+
getLocalName()
|
139
|
+
{
|
140
|
+
return stringOrNil(ruby, localName);
|
141
|
+
}
|
142
|
+
|
143
|
+
public IRubyObject
|
144
|
+
getName()
|
145
|
+
{
|
146
|
+
return stringOrNil(ruby, name);
|
147
|
+
}
|
148
|
+
|
149
|
+
public IRubyObject
|
150
|
+
getNamespaces(ThreadContext context)
|
151
|
+
{
|
152
|
+
final Ruby runtime = context.runtime;
|
153
|
+
if (namespaces == null) { return runtime.getNil(); }
|
154
|
+
RubyHash hash = RubyHash.newHash(runtime);
|
155
|
+
for (Map.Entry<String, String> entry : namespaces.entrySet()) {
|
156
|
+
IRubyObject k = stringOrBlank(runtime, entry.getKey());
|
157
|
+
IRubyObject v = stringOrBlank(runtime, entry.getValue());
|
158
|
+
hash.fastASetCheckString(runtime, k, v); // hash.op_aset(context, k, v)
|
105
159
|
}
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
160
|
+
return hash;
|
161
|
+
}
|
162
|
+
|
163
|
+
public IRubyObject
|
164
|
+
getXmlBase()
|
165
|
+
{
|
166
|
+
return stringOrNil(ruby, xmlBase);
|
167
|
+
}
|
168
|
+
|
169
|
+
public IRubyObject
|
170
|
+
getPrefix()
|
171
|
+
{
|
172
|
+
return stringOrNil(ruby, prefix);
|
173
|
+
}
|
174
|
+
|
175
|
+
public IRubyObject
|
176
|
+
getUri()
|
177
|
+
{
|
178
|
+
return stringOrNil(ruby, uri);
|
179
|
+
}
|
180
|
+
|
181
|
+
public IRubyObject
|
182
|
+
getValue()
|
183
|
+
{
|
184
|
+
return stringOrNil(ruby, value);
|
185
|
+
}
|
186
|
+
|
187
|
+
public IRubyObject
|
188
|
+
getXmlVersion()
|
189
|
+
{
|
190
|
+
return ruby.newString(xmlVersion);
|
191
|
+
}
|
192
|
+
|
193
|
+
public RubyBoolean
|
194
|
+
hasAttributes()
|
195
|
+
{
|
196
|
+
if (attributeList == null || attributeList.length == 0) { return ruby.getFalse(); }
|
197
|
+
return ruby.getTrue();
|
198
|
+
}
|
199
|
+
|
200
|
+
public abstract RubyBoolean hasValue();
|
201
|
+
|
202
|
+
public RubyBoolean
|
203
|
+
isDefault()
|
204
|
+
{
|
205
|
+
// TODO Implement.
|
206
|
+
return ruby.getFalse();
|
207
|
+
}
|
208
|
+
|
209
|
+
public boolean
|
210
|
+
isError() { return false; }
|
211
|
+
|
212
|
+
protected void
|
213
|
+
parsePrefix(String qName)
|
214
|
+
{
|
215
|
+
int index = qName.indexOf(':');
|
216
|
+
if (index != -1) { prefix = qName.substring(0, index); }
|
217
|
+
}
|
218
|
+
|
219
|
+
public void
|
220
|
+
setLang(String lang)
|
221
|
+
{
|
222
|
+
this.lang = lang;
|
223
|
+
}
|
224
|
+
|
225
|
+
public IRubyObject
|
226
|
+
toSyntaxError() { return ruby.getNil(); }
|
227
|
+
|
228
|
+
public IRubyObject
|
229
|
+
getNodeType() { return ruby.newFixnum(nodeType); }
|
230
|
+
|
231
|
+
public static enum ReaderNodeType {
|
232
|
+
NODE(0),
|
233
|
+
ELEMENT(1),
|
234
|
+
ATTRIBUTE(2),
|
235
|
+
TEXT(3),
|
236
|
+
CDATA(4),
|
237
|
+
ENTITY_REFERENCE(5),
|
238
|
+
ENTITY(6),
|
239
|
+
PROCESSING_INSTRUCTION(7),
|
240
|
+
COMMENT(8),
|
241
|
+
DOCUMENT(9),
|
242
|
+
DOCUMENT_TYPE(10),
|
243
|
+
DOCUMENTFRAGMENT(11),
|
244
|
+
NOTATION(12),
|
245
|
+
WHITESPACE(13),
|
246
|
+
SIGNIFICANT_WHITESPACE(14),
|
247
|
+
END_ELEMENT(15),
|
248
|
+
END_ENTITY(16),
|
249
|
+
XML_DECLARATION(17);
|
250
|
+
|
251
|
+
private final int value;
|
252
|
+
ReaderNodeType(int value)
|
253
|
+
{
|
254
|
+
this.value = value;
|
110
255
|
}
|
111
256
|
|
112
|
-
public
|
113
|
-
|
114
|
-
|
115
|
-
if (document == null) {
|
116
|
-
document = XmlDocument.createNewDocument(ruby);
|
117
|
-
}
|
118
|
-
for (int i=0; i<attributeList.length; i++) {
|
119
|
-
if (!isNamespace(attributeList.names.get(i))) {
|
120
|
-
Attr attr = document.createAttributeNS(attributeList.namespaces.get(i), attributeList.names.get(i));
|
121
|
-
attr.setValue(attributeList.values.get(i));
|
122
|
-
XmlAttr xmlAttr = new XmlAttr(ruby, attr);
|
123
|
-
array.append(xmlAttr);
|
124
|
-
}
|
125
|
-
}
|
126
|
-
}
|
127
|
-
return array;
|
257
|
+
public int getValue()
|
258
|
+
{
|
259
|
+
return value;
|
128
260
|
}
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
261
|
+
}
|
262
|
+
|
263
|
+
public static ClosingNode
|
264
|
+
createClosingNode(Ruby ruby, String uri, String localName, String qName, int depth, Stack<String> langStack,
|
265
|
+
Stack<String> xmlBaseStack)
|
266
|
+
{
|
267
|
+
return new ClosingNode(ruby, uri, localName, qName, depth, langStack, xmlBaseStack);
|
268
|
+
}
|
269
|
+
|
270
|
+
public static class ClosingNode extends ReaderNode
|
271
|
+
{
|
272
|
+
|
273
|
+
// public ClosingNode() {}
|
274
|
+
|
275
|
+
ClosingNode(Ruby runtime, String uri, String localName, String qName, int depth, Stack<String> langStack,
|
276
|
+
Stack<String> xmlBaseStack)
|
277
|
+
{
|
278
|
+
super(runtime);
|
279
|
+
nodeType = ReaderNodeType.END_ELEMENT.getValue();
|
280
|
+
this.uri = "".equals(uri) ? null : uri;
|
281
|
+
this.localName = ! isBlank(localName) ? localName : qName;
|
282
|
+
this.name = qName;
|
283
|
+
parsePrefix(qName);
|
284
|
+
this.depth = depth;
|
285
|
+
if (!langStack.isEmpty()) { this.lang = langStack.peek(); }
|
286
|
+
if (!xmlBaseStack.isEmpty()) { this.xmlBase = xmlBaseStack.peek(); }
|
140
287
|
}
|
141
288
|
|
142
|
-
|
143
|
-
|
289
|
+
@Override
|
290
|
+
public IRubyObject
|
291
|
+
getAttributeCount()
|
292
|
+
{
|
293
|
+
return ruby.newFixnum(0);
|
144
294
|
}
|
145
295
|
|
146
|
-
|
147
|
-
|
296
|
+
@Override
|
297
|
+
public RubyBoolean
|
298
|
+
hasValue()
|
299
|
+
{
|
300
|
+
return ruby.getFalse();
|
148
301
|
}
|
149
302
|
|
150
|
-
|
151
|
-
|
303
|
+
@Override
|
304
|
+
public String
|
305
|
+
getString()
|
306
|
+
{
|
307
|
+
return "</" + name + '>';
|
308
|
+
}
|
309
|
+
}
|
310
|
+
|
311
|
+
public static ElementNode
|
312
|
+
createElementNode(Ruby ruby, String uri, String localName, String qName, XMLAttributes attrs, int depth,
|
313
|
+
Stack<String> langStack, Stack<String> xmlBaseStack)
|
314
|
+
{
|
315
|
+
return new ElementNode(ruby, uri, localName, qName, attrs, depth, langStack, xmlBaseStack);
|
316
|
+
}
|
317
|
+
|
318
|
+
public static class ElementNode extends ReaderNode
|
319
|
+
{
|
320
|
+
|
321
|
+
// public ElementNode() {}
|
322
|
+
|
323
|
+
ElementNode(Ruby runtime, String uri, String localName, String qName, XMLAttributes attrs, int depth,
|
324
|
+
Stack<String> langStack, Stack<String> xmlBaseStack)
|
325
|
+
{
|
326
|
+
super(runtime);
|
327
|
+
this.nodeType = ReaderNodeType.ELEMENT.getValue();
|
328
|
+
this.uri = "".equals(uri) ? null : uri;
|
329
|
+
this.localName = ! isBlank(localName) ? localName : qName;
|
330
|
+
this.name = qName;
|
331
|
+
parsePrefix(qName);
|
332
|
+
this.depth = depth;
|
333
|
+
parseAttributes(attrs, langStack, xmlBaseStack);
|
152
334
|
}
|
153
335
|
|
154
|
-
|
155
|
-
|
336
|
+
@Override
|
337
|
+
public RubyBoolean
|
338
|
+
hasValue()
|
339
|
+
{
|
340
|
+
return ruby.getFalse();
|
156
341
|
}
|
157
342
|
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
343
|
+
private void
|
344
|
+
parseAttributes(XMLAttributes attrs, Stack<String> langStack, Stack<String> xmlBaseStack)
|
345
|
+
{
|
346
|
+
if (attrs.getLength() > 0) { attributeList = new ReaderAttributeList(); }
|
347
|
+
String u, n, v;
|
348
|
+
for (int i = 0; i < attrs.getLength(); i++) {
|
349
|
+
u = attrs.getURI(i);
|
350
|
+
n = attrs.getQName(i);
|
351
|
+
v = attrs.getValue(i);
|
352
|
+
if (isNamespace(n)) {
|
353
|
+
if (namespaces == null) { namespaces = new HashMap<String, String>(); }
|
354
|
+
namespaces.put(n, v);
|
355
|
+
} else {
|
356
|
+
if (lang == null) { lang = resolveLang(n, v, langStack); }
|
357
|
+
if (xmlBase == null) { xmlBase = resolveXmlBase(n, v, xmlBaseStack); }
|
166
358
|
}
|
167
|
-
|
359
|
+
attributeList.add(u, n, v);
|
360
|
+
}
|
168
361
|
}
|
169
362
|
|
170
|
-
|
171
|
-
|
363
|
+
private String
|
364
|
+
resolveLang(String n, String v, Stack<String> langStack)
|
365
|
+
{
|
366
|
+
if ("xml:lang".equals(n)) {
|
367
|
+
return v;
|
368
|
+
} else if (!langStack.isEmpty()) {
|
369
|
+
return langStack.peek();
|
370
|
+
} else {
|
371
|
+
return null;
|
372
|
+
}
|
172
373
|
}
|
173
374
|
|
174
|
-
|
175
|
-
|
375
|
+
private String
|
376
|
+
resolveXmlBase(String n, String v, Stack<String> xmlBaseStack)
|
377
|
+
{
|
378
|
+
if (isXmlBase(n)) {
|
379
|
+
return getXmlBaseUri(n, v, xmlBaseStack);
|
380
|
+
} else if (!xmlBaseStack.isEmpty()) {
|
381
|
+
return xmlBaseStack.peek();
|
382
|
+
} else {
|
383
|
+
return null;
|
384
|
+
}
|
176
385
|
}
|
177
386
|
|
178
|
-
|
179
|
-
|
387
|
+
private String
|
388
|
+
getXmlBaseUri(String n, String v, Stack<String> xmlBaseStack)
|
389
|
+
{
|
390
|
+
if ("xml:base".equals(n)) {
|
391
|
+
if (v.startsWith("http://")) {
|
392
|
+
return v;
|
393
|
+
} else if (v.startsWith("/") && v.endsWith("/")) {
|
394
|
+
String sub = v.substring(1, v.length() - 2);
|
395
|
+
String base = xmlBaseStack.peek();
|
396
|
+
if (base.endsWith("/")) {
|
397
|
+
base = base.substring(0, base.length() - 1);
|
398
|
+
}
|
399
|
+
int pos = base.lastIndexOf("/");
|
400
|
+
return base.substring(0, pos).concat(sub);
|
401
|
+
} else {
|
402
|
+
String base = xmlBaseStack.peek();
|
403
|
+
if (base.endsWith("/")) { return base.concat(v); }
|
404
|
+
else { return base.concat("/").concat(v); }
|
405
|
+
}
|
406
|
+
} else if ("xlink:href".equals(n)) {
|
407
|
+
if (v.startsWith("http://")) {
|
408
|
+
return v;
|
409
|
+
} else if (!xmlBaseStack.isEmpty()) {
|
410
|
+
String base = xmlBaseStack.peek();
|
411
|
+
return base;
|
412
|
+
}
|
413
|
+
}
|
414
|
+
return null;
|
180
415
|
}
|
181
416
|
|
182
|
-
|
183
|
-
|
417
|
+
@Override
|
418
|
+
public String
|
419
|
+
getString()
|
420
|
+
{
|
421
|
+
StringBuffer sb = new StringBuffer(24);
|
422
|
+
sb.append('<').append(name);
|
423
|
+
if (attributeList != null) {
|
424
|
+
for (int i = 0; i < attributeList.length; i++) {
|
425
|
+
String n = attributeList.names.get(i);
|
426
|
+
String v = attributeList.values.get(i);
|
427
|
+
sb.append(' ').append(n).append('=')
|
428
|
+
.append('"').append(v).append('"');
|
429
|
+
}
|
430
|
+
}
|
431
|
+
if (hasChildren) { sb.append('>'); }
|
432
|
+
else { sb.append("/>"); }
|
433
|
+
return sb.toString();
|
184
434
|
}
|
185
|
-
|
186
|
-
|
187
|
-
|
435
|
+
}
|
436
|
+
|
437
|
+
private static class ReaderAttributeList
|
438
|
+
{
|
439
|
+
final List<String> namespaces = new ArrayList<String>();
|
440
|
+
final List<String> names = new ArrayList<String>();
|
441
|
+
final List<String> values = new ArrayList<String>();
|
442
|
+
int length = 0;
|
443
|
+
|
444
|
+
void
|
445
|
+
add(String namespace, String name, String value)
|
446
|
+
{
|
447
|
+
namespaces.add(namespace != null ? namespace : "");
|
448
|
+
names.add(name != null ? name : "");
|
449
|
+
values.add(value != null ? value : "");
|
450
|
+
length++;
|
188
451
|
}
|
189
452
|
|
190
|
-
|
191
|
-
|
192
|
-
|
453
|
+
String
|
454
|
+
getByName(String name)
|
455
|
+
{
|
456
|
+
for (int i = 0; i < names.size(); i++) {
|
457
|
+
if (name.equals(names.get(i))) {
|
458
|
+
return values.get(i);
|
459
|
+
}
|
460
|
+
}
|
461
|
+
return null;
|
193
462
|
}
|
463
|
+
}
|
194
464
|
|
195
|
-
|
465
|
+
public static class EmptyNode extends ReaderNode
|
466
|
+
{
|
196
467
|
|
197
|
-
public
|
198
|
-
|
199
|
-
|
468
|
+
public
|
469
|
+
EmptyNode(Ruby runtime)
|
470
|
+
{
|
471
|
+
super(runtime);
|
472
|
+
this.nodeType = ReaderNodeType.NODE.getValue();
|
200
473
|
}
|
201
474
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
475
|
+
@Override
|
476
|
+
public IRubyObject
|
477
|
+
getXmlVersion()
|
478
|
+
{
|
479
|
+
return this.ruby.getNil();
|
207
480
|
}
|
208
481
|
|
209
|
-
|
210
|
-
|
482
|
+
@Override
|
483
|
+
public RubyBoolean
|
484
|
+
hasValue()
|
485
|
+
{
|
486
|
+
return ruby.getFalse();
|
211
487
|
}
|
212
488
|
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
NODE(0),
|
219
|
-
ELEMENT(1),
|
220
|
-
ATTRIBUTE(2),
|
221
|
-
TEXT(3),
|
222
|
-
CDATA(4),
|
223
|
-
ENTITY_REFERENCE(5),
|
224
|
-
ENTITY(6),
|
225
|
-
PROCESSING_INSTRUCTION(7),
|
226
|
-
COMMENT(8),
|
227
|
-
DOCUMENT(9),
|
228
|
-
DOCUMENT_TYPE(10),
|
229
|
-
DOCUMENTFRAGMENT(11),
|
230
|
-
NOTATION(12),
|
231
|
-
WHITESPACE(13),
|
232
|
-
SIGNIFICANT_WHITESPACE(14),
|
233
|
-
END_ELEMENT(15),
|
234
|
-
END_ENTITY(16),
|
235
|
-
XML_DECLARATION(17);
|
236
|
-
|
237
|
-
private final int value;
|
238
|
-
ReaderNodeType(int value) {
|
239
|
-
this.value = value;
|
240
|
-
}
|
241
|
-
|
242
|
-
public int getValue() {
|
243
|
-
return value;
|
244
|
-
}
|
489
|
+
@Override
|
490
|
+
public String
|
491
|
+
getString()
|
492
|
+
{
|
493
|
+
return null;
|
245
494
|
}
|
246
|
-
|
247
|
-
|
248
|
-
|
495
|
+
}
|
496
|
+
|
497
|
+
public static class ExceptionNode extends EmptyNode
|
498
|
+
{
|
499
|
+
private final XmlSyntaxError exception;
|
500
|
+
|
501
|
+
public
|
502
|
+
ExceptionNode(Ruby runtime, Exception ex)
|
503
|
+
{
|
504
|
+
super(runtime);
|
505
|
+
exception = XmlSyntaxError.createXMLSyntaxError(runtime); // Nokogiri::XML::SyntaxError
|
506
|
+
exception.setException(ex);
|
249
507
|
}
|
250
508
|
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
super(runtime);
|
257
|
-
nodeType = ReaderNodeType.END_ELEMENT.getValue();
|
258
|
-
this.uri = "".equals(uri) ? null : uri;
|
259
|
-
this.localName = ! isBlank(localName) ? localName : qName;
|
260
|
-
this.name = qName;
|
261
|
-
parsePrefix(qName);
|
262
|
-
this.depth = depth;
|
263
|
-
if (!langStack.isEmpty()) this.lang = langStack.peek();
|
264
|
-
if (!xmlBaseStack.isEmpty()) this.xmlBase = xmlBaseStack.peek();
|
265
|
-
}
|
266
|
-
|
267
|
-
@Override
|
268
|
-
public IRubyObject getAttributeCount() {
|
269
|
-
return ruby.newFixnum(0);
|
270
|
-
}
|
271
|
-
|
272
|
-
@Override
|
273
|
-
public RubyBoolean hasValue() {
|
274
|
-
return ruby.getFalse();
|
275
|
-
}
|
276
|
-
|
277
|
-
@Override
|
278
|
-
public String getString() {
|
279
|
-
return "</" + name + '>';
|
280
|
-
}
|
509
|
+
@Override
|
510
|
+
public boolean
|
511
|
+
isError()
|
512
|
+
{
|
513
|
+
return true;
|
281
514
|
}
|
282
515
|
|
283
|
-
|
284
|
-
|
516
|
+
@Override
|
517
|
+
public IRubyObject
|
518
|
+
toSyntaxError()
|
519
|
+
{
|
520
|
+
return this.exception;
|
285
521
|
}
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
for (int i = 0; i < attrs.getLength(); i++) {
|
311
|
-
u = attrs.getURI(i);
|
312
|
-
n = attrs.getQName(i);
|
313
|
-
v = attrs.getValue(i);
|
314
|
-
if (isNamespace(n)) {
|
315
|
-
if (namespaces == null) namespaces = new HashMap<String, String>();
|
316
|
-
namespaces.put(n, v);
|
317
|
-
} else {
|
318
|
-
if (lang == null) lang = resolveLang(n, v, langStack);
|
319
|
-
if (xmlBase == null) xmlBase = resolveXmlBase(n, v, xmlBaseStack);
|
320
|
-
}
|
321
|
-
attributeList.add(u, n, v);
|
322
|
-
}
|
323
|
-
}
|
324
|
-
|
325
|
-
private String resolveLang(String n, String v, Stack<String> langStack) {
|
326
|
-
if ("xml:lang".equals(n)) {
|
327
|
-
return v;
|
328
|
-
} else if (!langStack.isEmpty()) {
|
329
|
-
return langStack.peek();
|
330
|
-
} else {
|
331
|
-
return null;
|
332
|
-
}
|
333
|
-
}
|
334
|
-
|
335
|
-
private String resolveXmlBase(String n, String v, Stack<String> xmlBaseStack) {
|
336
|
-
if (isXmlBase(n)) {
|
337
|
-
return getXmlBaseUri(n, v, xmlBaseStack);
|
338
|
-
} else if (!xmlBaseStack.isEmpty()) {
|
339
|
-
return xmlBaseStack.peek();
|
340
|
-
} else {
|
341
|
-
return null;
|
342
|
-
}
|
343
|
-
}
|
344
|
-
|
345
|
-
private String getXmlBaseUri(String n, String v, Stack<String> xmlBaseStack) {
|
346
|
-
if ("xml:base".equals(n)) {
|
347
|
-
if (v.startsWith("http://")) {
|
348
|
-
return v;
|
349
|
-
} else if (v.startsWith("/") && v.endsWith("/")) {
|
350
|
-
String sub = v.substring(1, v.length() - 2);
|
351
|
-
String base = xmlBaseStack.peek();
|
352
|
-
if (base.endsWith("/")) {
|
353
|
-
base = base.substring(0, base.length() - 1);
|
354
|
-
}
|
355
|
-
int pos = base.lastIndexOf("/");
|
356
|
-
return base.substring(0, pos).concat(sub);
|
357
|
-
} else {
|
358
|
-
String base = xmlBaseStack.peek();
|
359
|
-
if (base.endsWith("/")) return base.concat(v);
|
360
|
-
else return base.concat("/").concat(v);
|
361
|
-
}
|
362
|
-
} else if ("xlink:href".equals(n)) {
|
363
|
-
if (v.startsWith("http://")) {
|
364
|
-
return v;
|
365
|
-
} else if (!xmlBaseStack.isEmpty()) {
|
366
|
-
String base = xmlBaseStack.peek();
|
367
|
-
return base;
|
368
|
-
}
|
369
|
-
}
|
370
|
-
return null;
|
371
|
-
}
|
372
|
-
|
373
|
-
@Override
|
374
|
-
public String getString() {
|
375
|
-
StringBuffer sb = new StringBuffer(24);
|
376
|
-
sb.append('<').append(name);
|
377
|
-
if (attributeList != null) {
|
378
|
-
for (int i=0; i<attributeList.length; i++) {
|
379
|
-
String n = attributeList.names.get(i);
|
380
|
-
String v = attributeList.values.get(i);
|
381
|
-
sb.append(' ').append(n).append('=')
|
382
|
-
.append('"').append(v).append('"');
|
383
|
-
}
|
384
|
-
}
|
385
|
-
if (hasChildren) sb.append('>');
|
386
|
-
else sb.append("/>");
|
387
|
-
return sb.toString();
|
388
|
-
}
|
522
|
+
}
|
523
|
+
|
524
|
+
public static TextNode
|
525
|
+
createTextNode(Ruby ruby, String content, int depth, Stack<String> langStack, Stack<String> xmlBaseStack)
|
526
|
+
{
|
527
|
+
return new TextNode(ruby, content, depth, langStack, xmlBaseStack);
|
528
|
+
}
|
529
|
+
|
530
|
+
public static class TextNode extends ReaderNode
|
531
|
+
{
|
532
|
+
|
533
|
+
// public TextNode() {}
|
534
|
+
|
535
|
+
TextNode(Ruby runtime, String content, int depth, Stack<String> langStack, Stack<String> xmlBaseStack)
|
536
|
+
{
|
537
|
+
super(runtime);
|
538
|
+
this.value = content;
|
539
|
+
this.localName = "#text";
|
540
|
+
this.name = "#text";
|
541
|
+
this.depth = depth;
|
542
|
+
if (!isBlank(content)) { nodeType = ReaderNodeType.TEXT.getValue(); }
|
543
|
+
else { nodeType = ReaderNodeType.SIGNIFICANT_WHITESPACE.getValue(); }
|
544
|
+
if (!langStack.isEmpty()) { this.lang = langStack.peek(); }
|
545
|
+
if (!xmlBaseStack.isEmpty()) { this.xmlBase = xmlBaseStack.peek(); }
|
389
546
|
}
|
390
547
|
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
void add(String namespace, String name, String value) {
|
398
|
-
namespaces.add(namespace != null ? namespace : "");
|
399
|
-
names.add(name != null ? name : "");
|
400
|
-
values.add(value != null ? value : "");
|
401
|
-
length++;
|
402
|
-
}
|
403
|
-
|
404
|
-
String getByName(String name) {
|
405
|
-
for (int i=0; i<names.size(); i++) {
|
406
|
-
if (name.equals(names.get(i))) {
|
407
|
-
return values.get(i);
|
408
|
-
}
|
409
|
-
}
|
410
|
-
return null;
|
411
|
-
}
|
548
|
+
@Override
|
549
|
+
public RubyBoolean
|
550
|
+
hasValue()
|
551
|
+
{
|
552
|
+
return ruby.getTrue();
|
412
553
|
}
|
413
554
|
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
}
|
420
|
-
|
421
|
-
@Override
|
422
|
-
public IRubyObject getXmlVersion() {
|
423
|
-
return this.ruby.getNil();
|
424
|
-
}
|
425
|
-
|
426
|
-
@Override
|
427
|
-
public RubyBoolean hasValue() {
|
428
|
-
return ruby.getFalse();
|
429
|
-
}
|
430
|
-
|
431
|
-
@Override
|
432
|
-
public String getString() {
|
433
|
-
return null;
|
434
|
-
}
|
435
|
-
}
|
436
|
-
|
437
|
-
public static class ExceptionNode extends EmptyNode {
|
438
|
-
private final XmlSyntaxError exception;
|
439
|
-
|
440
|
-
public ExceptionNode(Ruby runtime, Exception ex) {
|
441
|
-
super(runtime);
|
442
|
-
exception = XmlSyntaxError.createXMLSyntaxError(runtime); // Nokogiri::XML::SyntaxError
|
443
|
-
exception.setException(ex);
|
444
|
-
}
|
445
|
-
|
446
|
-
@Override
|
447
|
-
public boolean isError() {
|
448
|
-
return true;
|
449
|
-
}
|
450
|
-
|
451
|
-
@Override
|
452
|
-
public IRubyObject toSyntaxError() {
|
453
|
-
return this.exception;
|
454
|
-
}
|
455
|
-
}
|
456
|
-
|
457
|
-
public static TextNode createTextNode(Ruby ruby, String content, int depth, Stack<String> langStack, Stack<String> xmlBaseStack) {
|
458
|
-
return new TextNode(ruby, content, depth, langStack, xmlBaseStack);
|
459
|
-
}
|
460
|
-
|
461
|
-
public static class TextNode extends ReaderNode {
|
462
|
-
|
463
|
-
// public TextNode() {}
|
464
|
-
|
465
|
-
TextNode(Ruby runtime, String content, int depth, Stack<String> langStack, Stack<String> xmlBaseStack) {
|
466
|
-
super(runtime);
|
467
|
-
this.value = content;
|
468
|
-
this.localName = "#text";
|
469
|
-
this.name = "#text";
|
470
|
-
this.depth = depth;
|
471
|
-
if (!isBlank(content)) nodeType = ReaderNodeType.TEXT.getValue();
|
472
|
-
else nodeType = ReaderNodeType.SIGNIFICANT_WHITESPACE.getValue();
|
473
|
-
if (!langStack.isEmpty()) this.lang = langStack.peek();
|
474
|
-
if (!xmlBaseStack.isEmpty()) this.xmlBase = xmlBaseStack.peek();
|
475
|
-
}
|
476
|
-
|
477
|
-
@Override
|
478
|
-
public RubyBoolean hasValue() {
|
479
|
-
return ruby.getTrue();
|
480
|
-
}
|
481
|
-
|
482
|
-
@Override
|
483
|
-
public String getString() {
|
484
|
-
return value;
|
485
|
-
}
|
555
|
+
@Override
|
556
|
+
public String
|
557
|
+
getString()
|
558
|
+
{
|
559
|
+
return value;
|
486
560
|
}
|
561
|
+
}
|
487
562
|
|
488
563
|
}
|