nokogiri 1.6.1-java → 1.6.2-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/.editorconfig +17 -0
- data/.travis.yml +6 -6
- data/CHANGELOG.ja.rdoc +61 -8
- data/CHANGELOG.rdoc +58 -3
- data/Gemfile +3 -3
- data/Manifest.txt +57 -1
- data/README.ja.rdoc +22 -17
- data/README.rdoc +23 -18
- data/ROADMAP.md +1 -2
- data/Rakefile +162 -58
- data/build_all +56 -31
- data/dependencies.yml +3 -3
- data/ext/java/nokogiri/NokogiriService.java +9 -5
- data/ext/java/nokogiri/XmlDocument.java +95 -54
- data/ext/java/nokogiri/XmlNode.java +93 -42
- data/ext/java/nokogiri/XmlReader.java +1 -1
- data/ext/java/nokogiri/XmlSaxParserContext.java +33 -0
- data/ext/java/nokogiri/XmlSchema.java +4 -2
- data/ext/java/nokogiri/XmlXpathContext.java +118 -76
- data/ext/java/nokogiri/internals/IgnoreSchemaErrorsErrorHandler.java +20 -0
- data/ext/java/nokogiri/internals/NokogiriHandler.java +3 -10
- data/ext/java/nokogiri/internals/NokogiriHelpers.java +40 -23
- data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +59 -54
- data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +1 -1
- data/ext/java/nokogiri/internals/ParserContext.java +1 -4
- data/ext/java/nokogiri/internals/SaveContextVisitor.java +6 -2
- data/ext/java/nokogiri/internals/c14n/AttrCompare.java +119 -0
- data/ext/java/nokogiri/internals/c14n/C14nHelper.java +159 -0
- data/ext/java/nokogiri/internals/c14n/CanonicalFilter.java +37 -0
- data/ext/java/nokogiri/internals/c14n/CanonicalizationException.java +93 -0
- data/ext/java/nokogiri/internals/c14n/Canonicalizer.java +252 -0
- data/ext/java/nokogiri/internals/c14n/Canonicalizer11.java +639 -0
- data/ext/java/nokogiri/internals/c14n/Canonicalizer11_OmitComments.java +38 -0
- data/ext/java/nokogiri/internals/c14n/Canonicalizer11_WithComments.java +38 -0
- data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315.java +368 -0
- data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315Excl.java +295 -0
- data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315ExclOmitComments.java +40 -0
- data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315ExclWithComments.java +44 -0
- data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315OmitComments.java +44 -0
- data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315WithComments.java +43 -0
- data/ext/java/nokogiri/internals/c14n/CanonicalizerBase.java +630 -0
- data/ext/java/nokogiri/internals/c14n/CanonicalizerPhysical.java +173 -0
- data/ext/java/nokogiri/internals/c14n/CanonicalizerSpi.java +76 -0
- data/ext/java/nokogiri/internals/c14n/Constants.java +42 -0
- data/ext/java/nokogiri/internals/c14n/ElementProxy.java +293 -0
- data/ext/java/nokogiri/internals/c14n/HelperNodeList.java +93 -0
- data/ext/java/nokogiri/internals/c14n/IgnoreAllErrorHandler.java +79 -0
- data/ext/java/nokogiri/internals/c14n/InclusiveNamespaces.java +165 -0
- data/ext/java/nokogiri/internals/c14n/InvalidCanonicalizerException.java +76 -0
- data/ext/java/nokogiri/internals/c14n/NameSpaceSymbTable.java +402 -0
- data/ext/java/nokogiri/internals/c14n/NodeFilter.java +51 -0
- data/ext/java/nokogiri/internals/c14n/UtfHelpper.java +179 -0
- data/ext/java/nokogiri/internals/c14n/XMLUtils.java +507 -0
- data/ext/nokogiri/extconf.rb +429 -128
- data/ext/nokogiri/html_document.c +2 -2
- data/ext/nokogiri/nokogiri.c +6 -1
- data/ext/nokogiri/xml_document.c +5 -4
- data/ext/nokogiri/xml_node.c +76 -7
- data/ext/nokogiri/xml_reader.c +1 -1
- data/ext/nokogiri/xml_sax_parser_context.c +40 -0
- data/ext/nokogiri/xml_syntax_error.c +10 -5
- data/ext/nokogiri/xml_syntax_error.h +1 -1
- data/ext/nokogiri/xml_xpath_context.c +2 -14
- data/ext/nokogiri/xslt_stylesheet.c +1 -1
- data/lib/nokogiri.rb +31 -22
- data/lib/nokogiri/css/node.rb +0 -50
- data/lib/nokogiri/css/parser.rb +213 -218
- data/lib/nokogiri/css/parser.y +21 -30
- data/lib/nokogiri/css/xpath_visitor.rb +62 -14
- data/lib/nokogiri/html/document.rb +97 -18
- data/lib/nokogiri/html/sax/parser.rb +2 -2
- data/lib/nokogiri/nokogiri.jar +0 -0
- data/lib/nokogiri/version.rb +1 -1
- data/lib/nokogiri/xml/builder.rb +1 -1
- data/lib/nokogiri/xml/document.rb +2 -2
- data/lib/nokogiri/xml/dtd.rb +10 -0
- data/lib/nokogiri/xml/node.rb +26 -1
- data/lib/nokogiri/xml/sax/parser.rb +1 -1
- data/ports/patches/libxml2/0001-Fix-parser-local-buffers-size-problems.patch +265 -0
- data/ports/patches/libxml2/0002-Fix-entities-local-buffers-size-problems.patch +102 -0
- data/ports/patches/libxml2/0003-Fix-an-error-in-previous-commit.patch +26 -0
- data/ports/patches/libxml2/0004-Fix-potential-out-of-bound-access.patch +26 -0
- data/ports/patches/libxml2/0005-Detect-excessive-entities-expansion-upon-replacement.patch +158 -0
- data/ports/patches/libxml2/0006-Do-not-fetch-external-parsed-entities.patch +78 -0
- data/ports/patches/libxml2/0007-Enforce-XML_PARSER_EOF-state-handling-through-the-pa.patch +480 -0
- data/ports/patches/libxml2/0008-Improve-handling-of-xmlStopParser.patch +315 -0
- data/ports/patches/libxml2/0009-Fix-a-couple-of-return-without-value.patch +37 -0
- data/ports/patches/libxslt/0001-Adding-doc-update-related-to-1.1.28.patch +222 -0
- data/ports/patches/libxslt/0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch +53 -0
- data/ports/patches/libxslt/0003-Initialize-pseudo-random-number-generator-with-curre.patch +60 -0
- data/ports/patches/libxslt/0004-EXSLT-function-str-replace-is-broken-as-is.patch +42 -0
- data/ports/patches/libxslt/0006-Fix-str-padding-to-work-with-UTF-8-strings.patch +164 -0
- data/ports/patches/libxslt/0007-Separate-function-for-predicate-matching-in-patterns.patch +587 -0
- data/ports/patches/libxslt/0008-Fix-direct-pattern-matching.patch +80 -0
- data/ports/patches/libxslt/0009-Fix-certain-patterns-with-predicates.patch +185 -0
- data/ports/patches/libxslt/0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch +126 -0
- data/ports/patches/libxslt/0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch +25 -0
- data/ports/patches/libxslt/0014-Fix-for-bug-436589.patch +43 -0
- data/ports/patches/libxslt/0015-Fix-mkdir-for-mingw.patch +41 -0
- data/suppressions/README.txt +1 -0
- data/suppressions/nokogiri_ree-1.8.7.358.supp +61 -0
- data/suppressions/nokogiri_ruby-1.8.7.370.supp +0 -0
- data/suppressions/nokogiri_ruby-1.9.2.320.supp +28 -0
- data/suppressions/nokogiri_ruby-1.9.3.327.supp +28 -0
- data/test/css/test_nthiness.rb +65 -2
- data/test/css/test_parser.rb +27 -10
- data/test/css/test_tokenizer.rb +1 -1
- data/test/css/test_xpath_visitor.rb +6 -1
- data/test/files/atom.xml +344 -0
- data/test/files/shift_jis_no_charset.html +9 -0
- data/test/helper.rb +10 -0
- data/test/html/test_document.rb +74 -7
- data/test/html/test_document_encoding.rb +10 -0
- data/test/html/test_document_fragment.rb +9 -3
- data/test/namespaces/test_namespaces_aliased_default.rb +24 -0
- data/test/namespaces/test_namespaces_in_cloned_doc.rb +31 -0
- data/test/namespaces/test_namespaces_preservation.rb +31 -0
- data/test/test_nokogiri.rb +6 -0
- data/test/test_reader.rb +7 -4
- data/test/test_xslt_transforms.rb +25 -0
- data/test/xml/sax/test_parser.rb +16 -0
- data/test/xml/sax/test_parser_context.rb +9 -0
- data/test/xml/test_builder.rb +9 -0
- data/test/xml/test_c14n.rb +12 -2
- data/test/xml/test_document.rb +66 -0
- data/test/xml/test_document_fragment.rb +5 -0
- data/test/xml/test_dtd.rb +84 -0
- data/test/xml/test_entity_reference.rb +3 -3
- data/test/xml/test_node.rb +21 -3
- data/test/xml/test_node_attributes.rb +17 -0
- data/test/xml/test_schema.rb +26 -0
- data/test/xml/test_text.rb +15 -0
- data/test/xml/test_xpath.rb +87 -0
- data/test_all +3 -3
- metadata +119 -68
- data/tasks/cross_compile.rb +0 -134
@@ -244,7 +244,7 @@ public class XmlReader extends RubyObject {
|
|
244
244
|
// use the default options RECOVER | NONET
|
245
245
|
options = new ParserContext.Options(2048 | 1);
|
246
246
|
}
|
247
|
-
IRubyObject stringIO = NokogiriService.
|
247
|
+
IRubyObject stringIO = NokogiriService.getNokogiriClassCache(context.getRuntime()).get("StringIO").newInstance(context, args[0], Block.NULL_BLOCK);
|
248
248
|
InputStream in = new UncloseableInputStream(new IOInputStream(stringIO));
|
249
249
|
reader.setInput(context, in, url, options);
|
250
250
|
return reader;
|
@@ -75,11 +75,14 @@ public class XmlSaxParserContext extends ParserContext {
|
|
75
75
|
"http://xml.org/sax/features/namespace-prefixes";
|
76
76
|
protected static final String FEATURE_LOAD_EXTERNAL_DTD =
|
77
77
|
"http://apache.org/xml/features/nonvalidating/load-external-dtd";
|
78
|
+
protected static final String FEATURE_CONTINUE_AFTER_FATAL_ERROR =
|
79
|
+
"http://apache.org/xml/features/continue-after-fatal-error";
|
78
80
|
|
79
81
|
protected AbstractSAXParser parser;
|
80
82
|
|
81
83
|
protected NokogiriHandler handler = null;
|
82
84
|
private IRubyObject replaceEntities;
|
85
|
+
private IRubyObject recovery;
|
83
86
|
|
84
87
|
public XmlSaxParserContext(final Ruby ruby, RubyClass rubyClass) {
|
85
88
|
super(ruby, rubyClass);
|
@@ -87,6 +90,7 @@ public class XmlSaxParserContext extends ParserContext {
|
|
87
90
|
|
88
91
|
protected void initialize(Ruby runtime) {
|
89
92
|
replaceEntities = runtime.getTrue();
|
93
|
+
recovery = runtime.getFalse();
|
90
94
|
try {
|
91
95
|
parser = createParser();
|
92
96
|
} catch (SAXException se) {
|
@@ -199,6 +203,13 @@ public class XmlSaxParserContext extends ParserContext {
|
|
199
203
|
IRubyObject handlerRuby,
|
200
204
|
NokogiriHandler handler) {
|
201
205
|
((XmlSaxParser) parser).setXmlDeclHandler(handler);
|
206
|
+
if(recovery.isTrue()) {
|
207
|
+
try {
|
208
|
+
((XmlSaxParser) parser).setFeature(FEATURE_CONTINUE_AFTER_FATAL_ERROR, true);
|
209
|
+
} catch(Exception e) {
|
210
|
+
throw RaiseException.createNativeRaiseException(context.getRuntime(), e);
|
211
|
+
}
|
212
|
+
}
|
202
213
|
}
|
203
214
|
|
204
215
|
protected void postParse(ThreadContext context,
|
@@ -290,6 +301,28 @@ public class XmlSaxParserContext extends ParserContext {
|
|
290
301
|
return replaceEntities;
|
291
302
|
}
|
292
303
|
|
304
|
+
/**
|
305
|
+
* Can take a boolean assignment.
|
306
|
+
*
|
307
|
+
* @param context
|
308
|
+
* @param value
|
309
|
+
* @return
|
310
|
+
*/
|
311
|
+
@JRubyMethod(name = "recovery=")
|
312
|
+
public IRubyObject set_recovery(ThreadContext context,
|
313
|
+
IRubyObject value) {
|
314
|
+
if (!value.isTrue()) recovery = context.getRuntime().getFalse();
|
315
|
+
else recovery = context.getRuntime().getTrue();
|
316
|
+
|
317
|
+
return this;
|
318
|
+
}
|
319
|
+
|
320
|
+
@JRubyMethod(name="recovery")
|
321
|
+
public IRubyObject get_recovery(ThreadContext context) {
|
322
|
+
return recovery;
|
323
|
+
}
|
324
|
+
|
325
|
+
|
293
326
|
|
294
327
|
/**
|
295
328
|
* If the handler's document is a FragmentHandler, attempt to trim
|
@@ -32,8 +32,8 @@
|
|
32
32
|
|
33
33
|
package nokogiri;
|
34
34
|
|
35
|
-
import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
|
36
35
|
import static nokogiri.internals.NokogiriHelpers.adjustSystemIdIfNecessary;
|
36
|
+
import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
|
37
37
|
|
38
38
|
import java.io.IOException;
|
39
39
|
import java.io.InputStream;
|
@@ -48,6 +48,7 @@ import javax.xml.validation.Schema;
|
|
48
48
|
import javax.xml.validation.SchemaFactory;
|
49
49
|
import javax.xml.validation.Validator;
|
50
50
|
|
51
|
+
import nokogiri.internals.IgnoreSchemaErrorsErrorHandler;
|
51
52
|
import nokogiri.internals.SchemaErrorHandler;
|
52
53
|
import nokogiri.internals.XmlDomParserContext;
|
53
54
|
|
@@ -95,7 +96,8 @@ public class XmlSchema extends RubyObject {
|
|
95
96
|
private Schema getSchema(Source source, String currentDir, String scriptFileName) throws SAXException {
|
96
97
|
SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
|
97
98
|
SchemaResourceResolver resourceResolver = new SchemaResourceResolver(currentDir, scriptFileName, null);
|
98
|
-
schemaFactory.setResourceResolver(resourceResolver);
|
99
|
+
schemaFactory.setResourceResolver(resourceResolver);
|
100
|
+
schemaFactory.setErrorHandler(new IgnoreSchemaErrorsErrorHandler());
|
99
101
|
return schemaFactory.newSchema(source);
|
100
102
|
}
|
101
103
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* (The MIT License)
|
3
3
|
*
|
4
|
-
* Copyright (c) 2008 -
|
4
|
+
* Copyright (c) 2008 - 2014:
|
5
5
|
*
|
6
6
|
* * {Aaron Patterson}[http://tenderlovemaking.com]
|
7
7
|
* * {Mike Dalessio}[http://mike.daless.io]
|
@@ -34,13 +34,11 @@ package nokogiri;
|
|
34
34
|
|
35
35
|
import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
|
36
36
|
|
37
|
+
import java.lang.reflect.Constructor;
|
38
|
+
import java.lang.reflect.InvocationTargetException;
|
37
39
|
import java.util.Set;
|
38
|
-
import java.util.regex.Matcher;
|
39
|
-
import java.util.regex.Pattern;
|
40
40
|
|
41
|
-
import javax.xml.
|
42
|
-
import javax.xml.xpath.XPathConstants;
|
43
|
-
import javax.xml.xpath.XPathExpression;
|
41
|
+
import javax.xml.transform.TransformerException;
|
44
42
|
import javax.xml.xpath.XPathExpressionException;
|
45
43
|
import javax.xml.xpath.XPathFactory;
|
46
44
|
|
@@ -49,40 +47,82 @@ import nokogiri.internals.NokogiriXPathFunctionResolver;
|
|
49
47
|
import nokogiri.internals.NokogiriXPathVariableResolver;
|
50
48
|
|
51
49
|
import org.jruby.Ruby;
|
52
|
-
import org.jruby.RubyBoolean;
|
53
50
|
import org.jruby.RubyClass;
|
54
51
|
import org.jruby.RubyException;
|
55
|
-
import org.jruby.RubyFloat;
|
56
52
|
import org.jruby.RubyObject;
|
57
|
-
import org.jruby.RubyString;
|
58
53
|
import org.jruby.anno.JRubyClass;
|
59
54
|
import org.jruby.anno.JRubyMethod;
|
60
55
|
import org.jruby.exceptions.RaiseException;
|
61
56
|
import org.jruby.runtime.ThreadContext;
|
62
57
|
import org.jruby.runtime.builtin.IRubyObject;
|
58
|
+
import org.w3c.dom.Node;
|
63
59
|
import org.w3c.dom.NodeList;
|
64
60
|
|
61
|
+
import com.sun.org.apache.xml.internal.dtm.DTM;
|
62
|
+
import com.sun.org.apache.xml.internal.utils.PrefixResolver;
|
63
|
+
import com.sun.org.apache.xpath.internal.XPathContext;
|
64
|
+
import com.sun.org.apache.xpath.internal.jaxp.JAXPExtensionsProvider;
|
65
|
+
import com.sun.org.apache.xpath.internal.jaxp.JAXPPrefixResolver;
|
66
|
+
import com.sun.org.apache.xpath.internal.jaxp.JAXPVariableStack;
|
67
|
+
import com.sun.org.apache.xpath.internal.objects.XObject;
|
68
|
+
|
65
69
|
/**
|
66
70
|
* Class for Nokogiri::XML::XpathContext
|
67
71
|
*
|
68
72
|
* @author sergio
|
69
73
|
* @author Yoko Harada <yokolet@gmail.com>
|
74
|
+
* @author John Shahid <jvshahid@gmail.com>
|
70
75
|
*/
|
71
76
|
@JRubyClass(name="Nokogiri::XML::XPathContext")
|
72
77
|
public class XmlXpathContext extends RubyObject {
|
78
|
+
public final static String XPATH_CONTEXT = "CACHCED_XPATH_CONTEXT";
|
79
|
+
|
73
80
|
private XmlNode context;
|
74
|
-
private
|
75
|
-
|
81
|
+
private final NokogiriXPathFunctionResolver functionResolver;
|
82
|
+
private final NokogiriXPathVariableResolver variableResolver;
|
83
|
+
private PrefixResolver prefixResolver;
|
84
|
+
private XPathContext xpathSupport = null;
|
85
|
+
private NokogiriNamespaceContext nsContext;
|
86
|
+
|
76
87
|
public XmlXpathContext(Ruby ruby, RubyClass rubyClass) {
|
77
88
|
super(ruby, rubyClass);
|
89
|
+
functionResolver = NokogiriXPathFunctionResolver.create(ruby.getCurrentContext().nil);
|
90
|
+
variableResolver = NokogiriXPathVariableResolver.create();
|
78
91
|
}
|
79
|
-
|
80
|
-
|
92
|
+
|
93
|
+
private void setNode(XmlNode node) throws IllegalArgumentException, ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException {
|
94
|
+
Node doc = node.getNode().getOwnerDocument();
|
95
|
+
if (doc == null) {
|
96
|
+
doc = node.getNode();
|
97
|
+
}
|
98
|
+
xpathSupport = (XPathContext) doc.getUserData(XPATH_CONTEXT);
|
99
|
+
|
100
|
+
if (xpathSupport == null) {
|
101
|
+
JAXPExtensionsProvider jep = getProviderInstance();
|
102
|
+
xpathSupport = new XPathContext(jep);
|
103
|
+
xpathSupport.setVarStack(new JAXPVariableStack(variableResolver));
|
104
|
+
doc.setUserData(XPATH_CONTEXT, xpathSupport, null);
|
105
|
+
}
|
106
|
+
|
81
107
|
context = node;
|
82
|
-
|
83
|
-
|
108
|
+
nsContext = NokogiriNamespaceContext.create();
|
109
|
+
prefixResolver = new JAXPPrefixResolver(nsContext);
|
110
|
+
}
|
111
|
+
|
112
|
+
private JAXPExtensionsProvider getProviderInstance() throws ClassNotFoundException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
|
113
|
+
Class<?> clazz = Class.forName("com.sun.org.apache.xpath.internal.jaxp.JAXPExtensionsProvider");
|
114
|
+
Constructor[] constructors = clazz.getDeclaredConstructors();
|
115
|
+
for (int i = 0; i < constructors.length; i++) {
|
116
|
+
Class[] parameterTypes = constructors[i].getParameterTypes();
|
117
|
+
if (parameterTypes.length == 2) {
|
118
|
+
return (JAXPExtensionsProvider) constructors[i].newInstance(functionResolver, false);
|
119
|
+
} else if (parameterTypes.length == 1) {
|
120
|
+
return (JAXPExtensionsProvider) constructors[i].newInstance(functionResolver);
|
121
|
+
}
|
122
|
+
}
|
123
|
+
return null;
|
84
124
|
}
|
85
|
-
|
125
|
+
|
86
126
|
/**
|
87
127
|
* Create and return a copy of this object.
|
88
128
|
*
|
@@ -97,83 +137,86 @@ public class XmlXpathContext extends RubyObject {
|
|
97
137
|
public static IRubyObject rbNew(ThreadContext thread_context, IRubyObject klazz, IRubyObject node) {
|
98
138
|
XmlNode xmlNode = (XmlNode)node;
|
99
139
|
XmlXpathContext xmlXpathContext = (XmlXpathContext) NokogiriService.XML_XPATHCONTEXT_ALLOCATOR.allocate(thread_context.getRuntime(), (RubyClass)klazz);
|
100
|
-
|
101
|
-
|
140
|
+
XPathFactory.newInstance().newXPath();
|
141
|
+
try {
|
142
|
+
xmlXpathContext.setNode(xmlNode);
|
143
|
+
} catch (IllegalArgumentException e) {
|
144
|
+
throw thread_context.getRuntime().newRuntimeError(e.getMessage());
|
145
|
+
} catch (ClassNotFoundException e) {
|
146
|
+
throw thread_context.getRuntime().newRuntimeError(e.getMessage());
|
147
|
+
} catch (InstantiationException e) {
|
148
|
+
throw thread_context.getRuntime().newRuntimeError(e.getMessage());
|
149
|
+
} catch (IllegalAccessException e) {
|
150
|
+
throw thread_context.getRuntime().newRuntimeError(e.getMessage());
|
151
|
+
} catch (InvocationTargetException e) {
|
152
|
+
throw thread_context.getRuntime().newRuntimeError(e.getMessage());
|
153
|
+
}
|
102
154
|
return xmlXpathContext;
|
103
155
|
}
|
104
156
|
|
105
157
|
@JRubyMethod
|
106
158
|
public IRubyObject evaluate(ThreadContext thread_context, IRubyObject expr, IRubyObject handler) {
|
159
|
+
functionResolver.setHandler(handler);
|
107
160
|
String src = (String) expr.toJava(String.class);
|
108
|
-
|
109
|
-
if(!
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
src = src.replaceAll(name, NokogiriNamespaceContext.NOKOGIRI_PREFIX+":"+name);
|
114
|
-
}
|
161
|
+
if(!handler.isNil()) {
|
162
|
+
if (!isContainsPrefix(src)) {
|
163
|
+
Set<String> methodNames = handler.getMetaClass().getMethods().keySet();
|
164
|
+
for (String name : methodNames) {
|
165
|
+
src = src.replaceAll(name, NokogiriNamespaceContext.NOKOGIRI_PREFIX+":"+name);
|
115
166
|
}
|
116
|
-
xpath.setXPathFunctionResolver(NokogiriXPathFunctionResolver.create(handler));
|
117
167
|
}
|
118
|
-
XPathExpression xpathExpression = xpath.compile(src);
|
119
|
-
return node_set(thread_context, xpathExpression);
|
120
|
-
} catch (XPathExpressionException xpee) {
|
121
|
-
xpee = new XPathExpressionException(src);
|
122
|
-
RubyException e = XmlSyntaxError.createXPathSyntaxError(getRuntime(), xpee);
|
123
|
-
throw new RaiseException(e);
|
124
168
|
}
|
169
|
+
return node_set(thread_context, src);
|
125
170
|
}
|
126
171
|
|
127
|
-
protected IRubyObject node_set(ThreadContext thread_context,
|
128
|
-
|
129
|
-
|
130
|
-
result = tryGetNodeSet(thread_context, xpathExpression);
|
131
|
-
return result;
|
172
|
+
protected IRubyObject node_set(ThreadContext thread_context, String expr) {
|
173
|
+
try {
|
174
|
+
return tryGetNodeSet(thread_context, expr);
|
132
175
|
} catch (XPathExpressionException xpee) {
|
133
|
-
|
134
|
-
|
135
|
-
} catch (XPathExpressionException xpee_opaque) {
|
136
|
-
RubyException e = XmlSyntaxError.createXPathSyntaxError(getRuntime(), xpee_opaque);
|
137
|
-
throw new RaiseException(e);
|
138
|
-
}
|
176
|
+
RubyException e = XmlSyntaxError.createXPathSyntaxError(getRuntime(), xpee);
|
177
|
+
throw new RaiseException(e);
|
139
178
|
}
|
140
179
|
}
|
141
|
-
|
142
|
-
private XmlNodeSet tryGetNodeSet(ThreadContext thread_context, XPathExpression xpathExpression) throws XPathExpressionException {
|
143
|
-
NodeList nodeList = (NodeList)xpathExpression.evaluate(context.node, XPathConstants.NODESET);
|
144
|
-
XmlNodeSet xmlNodeSet = (XmlNodeSet) NokogiriService.XML_NODESET_ALLOCATOR.allocate(getRuntime(), getNokogiriClass(getRuntime(), "Nokogiri::XML::NodeSet"));
|
145
|
-
xmlNodeSet.setNodeList(nodeList);
|
146
|
-
xmlNodeSet.initialize(thread_context.getRuntime(), context);
|
147
|
-
return xmlNodeSet;
|
148
|
-
}
|
149
180
|
|
150
|
-
private
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
if ((value = getDoubleValue(string)) != null) {
|
156
|
-
return new RubyFloat(getRuntime(), value);
|
157
|
-
}
|
158
|
-
if (doesMatch(boolean_pattern, string.toLowerCase())) return RubyBoolean.newBoolean(getRuntime(), Boolean.parseBoolean(string));
|
159
|
-
return RubyString.newString(getRuntime(), string);
|
160
|
-
}
|
161
|
-
|
162
|
-
private Double getDoubleValue(String value) {
|
181
|
+
private IRubyObject tryGetNodeSet(ThreadContext thread_context, String expr) throws XPathExpressionException {
|
182
|
+
XObject xobj = null;
|
183
|
+
|
184
|
+
Node contextNode = context.node;
|
185
|
+
|
163
186
|
try {
|
164
|
-
|
165
|
-
|
166
|
-
|
187
|
+
com.sun.org.apache.xpath.internal.XPath xpathInternal = new com.sun.org.apache.xpath.internal.XPath (expr, null,
|
188
|
+
prefixResolver, com.sun.org.apache.xpath.internal.XPath.SELECT );
|
189
|
+
|
190
|
+
// We always need to have a ContextNode with Xalan XPath implementation
|
191
|
+
// To allow simple expression evaluation like 1+1 we are setting
|
192
|
+
// dummy Document as Context Node
|
193
|
+
|
194
|
+
if ( contextNode == null )
|
195
|
+
xobj = xpathInternal.execute(xpathSupport, DTM.NULL, prefixResolver);
|
196
|
+
else
|
197
|
+
xobj = xpathInternal.execute(xpathSupport, contextNode, prefixResolver);
|
198
|
+
|
199
|
+
switch (xobj.getType()) {
|
200
|
+
case XObject.CLASS_BOOLEAN:
|
201
|
+
return thread_context.getRuntime().newBoolean(xobj.bool());
|
202
|
+
case XObject.CLASS_NUMBER:
|
203
|
+
return thread_context.getRuntime().newFloat(xobj.num());
|
204
|
+
case XObject.CLASS_NODESET:
|
205
|
+
NodeList nodeList = xobj.nodelist();
|
206
|
+
XmlNodeSet xmlNodeSet = (XmlNodeSet) NokogiriService.XML_NODESET_ALLOCATOR.allocate(getRuntime(), getNokogiriClass(getRuntime(), "Nokogiri::XML::NodeSet"));
|
207
|
+
xmlNodeSet.setNodeList(nodeList);
|
208
|
+
xmlNodeSet.initialize(thread_context.getRuntime(), context);
|
209
|
+
return xmlNodeSet;
|
210
|
+
default:
|
211
|
+
return thread_context.getRuntime().newString(xobj.str());
|
212
|
+
}
|
213
|
+
} catch(TransformerException ex) {
|
214
|
+
throw new XPathExpressionException(expr);
|
167
215
|
}
|
168
216
|
}
|
169
|
-
|
170
|
-
private boolean doesMatch(Pattern pattern, String string) {
|
171
|
-
Matcher m = pattern.matcher(string);
|
172
|
-
return m.matches();
|
173
|
-
}
|
174
217
|
|
175
218
|
private boolean isContainsPrefix(String str) {
|
176
|
-
Set<String> prefixes =
|
219
|
+
Set<String> prefixes = nsContext.getAllPrefixes();
|
177
220
|
for (String prefix : prefixes) {
|
178
221
|
if (str.contains(prefix + ":")) {
|
179
222
|
return true;
|
@@ -190,14 +233,13 @@ public class XmlXpathContext extends RubyObject {
|
|
190
233
|
|
191
234
|
@JRubyMethod
|
192
235
|
public IRubyObject register_ns(ThreadContext context, IRubyObject prefix, IRubyObject uri) {
|
193
|
-
|
236
|
+
nsContext.registerNamespace((String)prefix.toJava(String.class), (String)uri.toJava(String.class));
|
194
237
|
return this;
|
195
238
|
}
|
196
239
|
|
197
240
|
@JRubyMethod
|
198
241
|
public IRubyObject register_variable(ThreadContext context, IRubyObject name, IRubyObject value) {
|
199
|
-
((
|
200
|
-
registerVariable((String)name.toJava(String.class), (String)value.toJava(String.class));
|
242
|
+
variableResolver.registerVariable((String)name.toJava(String.class), (String)value.toJava(String.class));
|
201
243
|
return this;
|
202
244
|
}
|
203
245
|
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
package nokogiri.internals;
|
2
|
+
|
3
|
+
import org.xml.sax.ErrorHandler;
|
4
|
+
import org.xml.sax.SAXException;
|
5
|
+
import org.xml.sax.SAXParseException;
|
6
|
+
|
7
|
+
public class IgnoreSchemaErrorsErrorHandler implements ErrorHandler {
|
8
|
+
|
9
|
+
@Override
|
10
|
+
public void warning(SAXParseException exception) throws SAXException {
|
11
|
+
}
|
12
|
+
|
13
|
+
@Override
|
14
|
+
public void error(SAXParseException exception) throws SAXException {
|
15
|
+
}
|
16
|
+
|
17
|
+
@Override
|
18
|
+
public void fatalError(SAXParseException exception) throws SAXException {
|
19
|
+
}
|
20
|
+
}
|
@@ -76,8 +76,6 @@ public class NokogiriHandler extends DefaultHandler2 implements XmlDeclHandler {
|
|
76
76
|
private final LinkedList<XmlSyntaxError> errors = new LinkedList<XmlSyntaxError>();
|
77
77
|
|
78
78
|
private Locator locator;
|
79
|
-
private final ArrayDeque<Integer> lines;
|
80
|
-
private final ArrayDeque<Integer> columns;
|
81
79
|
private static String htmlParserName = "Nokogiri::HTML::SAX::Parser";
|
82
80
|
private boolean needEmptyAttrCheck = false;
|
83
81
|
|
@@ -85,8 +83,6 @@ public class NokogiriHandler extends DefaultHandler2 implements XmlDeclHandler {
|
|
85
83
|
this.ruby = runtime;
|
86
84
|
this.attrClass = (RubyClass) runtime.getClassFromPath("Nokogiri::XML::SAX::Parser::Attribute");
|
87
85
|
this.object = object;
|
88
|
-
lines = new ArrayDeque<Integer>();
|
89
|
-
columns = new ArrayDeque<Integer>();
|
90
86
|
String objectName = object.getMetaClass().getName();
|
91
87
|
if (htmlParserName.equals(objectName)) needEmptyAttrCheck = true;
|
92
88
|
}
|
@@ -141,10 +137,7 @@ public class NokogiriHandler extends DefaultHandler2 implements XmlDeclHandler {
|
|
141
137
|
|
142
138
|
ThreadContext context = ruby.getCurrentContext();
|
143
139
|
boolean fromFragmentHandler = false; // isFromFragmentHandler();
|
144
|
-
|
145
|
-
lines.add(locator.getLineNumber());
|
146
|
-
columns.add(locator.getColumnNumber() - 1); // libxml counts from 0 while java does from 1
|
147
|
-
|
140
|
+
|
148
141
|
for (int i = 0; i < attrs.getLength(); i++) {
|
149
142
|
String u = attrs.getURI(i);
|
150
143
|
String qn = attrs.getQName(i);
|
@@ -208,11 +201,11 @@ public class NokogiriHandler extends DefaultHandler2 implements XmlDeclHandler {
|
|
208
201
|
}
|
209
202
|
|
210
203
|
public Integer getLine() {
|
211
|
-
return
|
204
|
+
return locator.getLineNumber();
|
212
205
|
}
|
213
206
|
|
214
207
|
public Integer getColumn() {
|
215
|
-
return
|
208
|
+
return locator.getColumnNumber() - 1;
|
216
209
|
}
|
217
210
|
|
218
211
|
private boolean isFromFragmentHandler() {
|
@@ -1,7 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* (The MIT License)
|
3
3
|
*
|
4
|
-
* Copyright (c) 2008 -
|
4
|
+
* Copyright (c) 2008 - 2014:
|
5
5
|
*
|
6
6
|
* * {Aaron Patterson}[http://tenderlovemaking.com]
|
7
7
|
* * {Mike Dalessio}[http://mike.daless.io]
|
@@ -60,6 +60,7 @@ import nokogiri.XmlNamespace;
|
|
60
60
|
import nokogiri.XmlNode;
|
61
61
|
import nokogiri.XmlProcessingInstruction;
|
62
62
|
import nokogiri.XmlText;
|
63
|
+
import nokogiri.XmlXpathContext;
|
63
64
|
|
64
65
|
import org.jcodings.specific.UTF8Encoding;
|
65
66
|
import org.jruby.Ruby;
|
@@ -93,6 +94,20 @@ public class NokogiriHelpers {
|
|
93
94
|
return (XmlNode) node.getUserData(CACHED_NODE);
|
94
95
|
}
|
95
96
|
|
97
|
+
public static void clearCachedNode(Node node) {
|
98
|
+
node.setUserData(CACHED_NODE, null, null);
|
99
|
+
}
|
100
|
+
|
101
|
+
public static void clearXpathContext(Node node) {
|
102
|
+
if (node == null) return;
|
103
|
+
|
104
|
+
Node ownerDocument = node.getOwnerDocument();
|
105
|
+
if (ownerDocument == null) {
|
106
|
+
ownerDocument = node;
|
107
|
+
}
|
108
|
+
ownerDocument.setUserData(XmlXpathContext.XPATH_CONTEXT, null, null);
|
109
|
+
}
|
110
|
+
|
96
111
|
/**
|
97
112
|
* Get the XmlNode associated with the underlying
|
98
113
|
* <code>node</code>. Creates a new XmlNode (or appropriate subclass)
|
@@ -175,7 +190,7 @@ public class NokogiriHelpers {
|
|
175
190
|
}
|
176
191
|
|
177
192
|
public static RubyClass getNokogiriClass(Ruby ruby, String name) {
|
178
|
-
return NokogiriService.
|
193
|
+
return NokogiriService.getNokogiriClassCache(ruby).get(name);
|
179
194
|
}
|
180
195
|
|
181
196
|
public static IRubyObject stringOrNil(Ruby runtime, String s) {
|
@@ -542,7 +557,7 @@ public class NokogiriHelpers {
|
|
542
557
|
private static Pattern decoded_pattern = Pattern.compile("&|>|<|\r");
|
543
558
|
private static String[] encoded = {"&", ">", "<", " "};
|
544
559
|
private static String[] decoded = {"&", ">", "<", "\r"};
|
545
|
-
|
560
|
+
|
546
561
|
private static String convert(Pattern ptn, String input, String[] oldChars, String[] newChars) {
|
547
562
|
Matcher matcher = ptn.matcher(input);
|
548
563
|
boolean result = matcher.find();
|
@@ -562,11 +577,11 @@ public class NokogiriHelpers {
|
|
562
577
|
matcher.appendTail(sb);
|
563
578
|
return sb.toString();
|
564
579
|
}
|
565
|
-
|
580
|
+
|
566
581
|
public static String encodeJavaString(String s) {
|
567
582
|
return convert(decoded_pattern, s, decoded, encoded);
|
568
583
|
}
|
569
|
-
|
584
|
+
|
570
585
|
public static String decodeJavaString(String s) {
|
571
586
|
return convert(encoded_pattern, s, encoded, decoded);
|
572
587
|
}
|
@@ -602,7 +617,7 @@ public class NokogiriHelpers {
|
|
602
617
|
public static boolean isXmlBase(String attrName) {
|
603
618
|
return "xml:base".equals(attrName) || "xlink:href".equals(attrName);
|
604
619
|
}
|
605
|
-
|
620
|
+
|
606
621
|
public static boolean isWhitespaceText(ThreadContext context, IRubyObject obj) {
|
607
622
|
if (obj == null || obj.isNil()) return false;
|
608
623
|
|
@@ -613,11 +628,11 @@ public class NokogiriHelpers {
|
|
613
628
|
String content = rubyStringToString(node.content(context));
|
614
629
|
return content.trim().length() == 0;
|
615
630
|
}
|
616
|
-
|
631
|
+
|
617
632
|
public static boolean isWhitespaceText(String s) {
|
618
633
|
return s.trim().length() == 0;
|
619
634
|
}
|
620
|
-
|
635
|
+
|
621
636
|
public static String canonicalizeWhitespce(String s) {
|
622
637
|
StringBuilder sb = new StringBuilder();
|
623
638
|
char[] chars = s.toCharArray();
|
@@ -648,14 +663,14 @@ public class NokogiriHelpers {
|
|
648
663
|
RubyArray array = RubyArray.newArray(ruby, nodes.getLength());
|
649
664
|
return nodeListToRubyArray(ruby, nodes, array);
|
650
665
|
}
|
651
|
-
|
666
|
+
|
652
667
|
public static RubyArray nodeListToRubyArray(Ruby ruby, NodeList nodes, RubyArray array) {
|
653
668
|
for(int i = 0; i < nodes.getLength(); i++) {
|
654
669
|
array.append(NokogiriHelpers.getCachedNodeOrCreate(ruby, nodes.item(i)));
|
655
670
|
}
|
656
671
|
return array;
|
657
672
|
}
|
658
|
-
|
673
|
+
|
659
674
|
public static RubyArray nodeArrayToRubyArray(Ruby ruby, Node[] nodes) {
|
660
675
|
RubyArray n = RubyArray.newArray(ruby, nodes.length);
|
661
676
|
for(int i = 0; i < nodes.length; i++) {
|
@@ -663,7 +678,7 @@ public class NokogiriHelpers {
|
|
663
678
|
}
|
664
679
|
return n;
|
665
680
|
}
|
666
|
-
|
681
|
+
|
667
682
|
public static RubyArray namedNodeMapToRubyArray(Ruby ruby, NamedNodeMap map) {
|
668
683
|
RubyArray n = RubyArray.newArray(ruby, map.getLength());
|
669
684
|
for(int i = 0; i < map.getLength(); i++) {
|
@@ -671,7 +686,7 @@ public class NokogiriHelpers {
|
|
671
686
|
}
|
672
687
|
return n;
|
673
688
|
}
|
674
|
-
|
689
|
+
|
675
690
|
public static String getValidEncoding(Ruby runtime, IRubyObject encoding) {
|
676
691
|
if (encoding.isNil()) {
|
677
692
|
return guessEncoding();
|
@@ -679,7 +694,7 @@ public class NokogiriHelpers {
|
|
679
694
|
return ignoreInvalidEncoding(runtime, encoding);
|
680
695
|
}
|
681
696
|
}
|
682
|
-
|
697
|
+
|
683
698
|
private static String guessEncoding() {
|
684
699
|
String name = null;
|
685
700
|
if (name == null) name = System.getProperty("file.encoding");
|
@@ -694,7 +709,7 @@ public class NokogiriHelpers {
|
|
694
709
|
if (charsetNames.contains(givenEncoding)) return givenEncoding;
|
695
710
|
else return guessEncoding();
|
696
711
|
}
|
697
|
-
|
712
|
+
|
698
713
|
public static String adjustSystemIdIfNecessary(String currentDir, String scriptFileName, String baseURI, String systemId) {
|
699
714
|
if (systemId == null) return systemId;
|
700
715
|
File file = new File(systemId);
|
@@ -705,7 +720,7 @@ public class NokogiriHelpers {
|
|
705
720
|
if (path != null) return path;
|
706
721
|
return resolveSystemId(scriptFileName, systemId);
|
707
722
|
}
|
708
|
-
|
723
|
+
|
709
724
|
private static String resolveSystemId(String baseName, String systemId) {
|
710
725
|
if (baseName == null || baseName.length() < 1) return null;
|
711
726
|
String parentName = null;
|
@@ -719,13 +734,13 @@ public class NokogiriHelpers {
|
|
719
734
|
if (dtdFile.exists()) return dtdFile.getPath();
|
720
735
|
return null;
|
721
736
|
}
|
722
|
-
|
737
|
+
|
723
738
|
public static boolean isUTF8(String encoding) {
|
724
739
|
if (encoding == null) return true; // no need to convert encoding
|
725
740
|
int ret = Charset.forName(encoding).compareTo(Charset.forName("UTF-8"));
|
726
741
|
return ret == 0;
|
727
742
|
}
|
728
|
-
|
743
|
+
|
729
744
|
public static byte[] convertEncoding(Charset output_charset, String input_string) throws CharacterCodingException {
|
730
745
|
CharsetEncoder encoder = output_charset.newEncoder();
|
731
746
|
CharBuffer charBuffer = CharBuffer.wrap(input_string);
|
@@ -746,7 +761,6 @@ public class NokogiriHelpers {
|
|
746
761
|
} else {
|
747
762
|
return NokogiriHelpers.nkf(runtime, ruby_encoding, thing);
|
748
763
|
}
|
749
|
-
|
750
764
|
}
|
751
765
|
|
752
766
|
// This method is used from HTML documents. HTML meta tag with encoding specification
|
@@ -775,7 +789,7 @@ public class NokogiriHelpers {
|
|
775
789
|
} catch (ClassNotFoundException e1) {
|
776
790
|
try {
|
777
791
|
// Before JRuby 1.7
|
778
|
-
nkfClass = runtime.getClassLoader().loadClass("org.jruby.RubyNKF");
|
792
|
+
nkfClass = runtime.getClassLoader().loadClass("org.jruby.RubyNKF");
|
779
793
|
} catch (ClassNotFoundException e2) {
|
780
794
|
return thing;
|
781
795
|
}
|
@@ -798,7 +812,7 @@ public class NokogiriHelpers {
|
|
798
812
|
return thing;
|
799
813
|
}
|
800
814
|
}
|
801
|
-
|
815
|
+
|
802
816
|
private static Charset shift_jis = Charset.forName("Shift_JIS");
|
803
817
|
private static Charset jis = Charset.forName("ISO-2022-JP");
|
804
818
|
private static Charset euc_jp = Charset.forName("EUC-JP");
|
@@ -812,11 +826,14 @@ public class NokogiriHelpers {
|
|
812
826
|
return !shouldEncode(text);
|
813
827
|
}
|
814
828
|
|
829
|
+
public static NokogiriNamespaceCache getNamespaceCacheFormNode(Node n) {
|
830
|
+
XmlDocument xmlDoc = (XmlDocument)getCachedNode(n.getOwnerDocument());
|
831
|
+
return xmlDoc.getNamespaceCache();
|
832
|
+
}
|
833
|
+
|
815
834
|
public static Node renameNode(Node n, String namespaceURI, String qualifiedName) throws DOMException {
|
816
835
|
Document doc = n.getOwnerDocument();
|
817
|
-
|
818
|
-
NokogiriNamespaceCache nsCache = xmlDoc.getNamespaceCache();
|
819
|
-
int oldHash = n.hashCode();
|
836
|
+
NokogiriNamespaceCache nsCache = getNamespaceCacheFormNode(n);
|
820
837
|
Node result = doc.renameNode(n, namespaceURI, qualifiedName);
|
821
838
|
if (result != n) {
|
822
839
|
nsCache.replaceNode(n, result);
|