nokogiri 1.5.2-java → 1.5.3-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.

Files changed (70) hide show
  1. data/CHANGELOG.ja.rdoc +35 -0
  2. data/CHANGELOG.rdoc +37 -2
  3. data/Manifest.txt +11 -3
  4. data/README.rdoc +1 -1
  5. data/ROADMAP.md +86 -0
  6. data/{nokogiri_help_responses.md → STANDARD_RESPONSES.md} +11 -4
  7. data/Y_U_NO_GEMSPEC.md +155 -0
  8. data/build_all +58 -0
  9. data/ext/java/nokogiri/HtmlDocument.java +10 -1
  10. data/ext/java/nokogiri/XmlAttr.java +11 -1
  11. data/ext/java/nokogiri/XmlDocument.java +4 -0
  12. data/ext/java/nokogiri/XmlNamespace.java +25 -0
  13. data/ext/java/nokogiri/XmlNode.java +6 -6
  14. data/ext/java/nokogiri/XmlReader.java +19 -4
  15. data/ext/java/nokogiri/XmlSaxPushParser.java +88 -57
  16. data/ext/java/nokogiri/XmlSyntaxError.java +15 -3
  17. data/ext/java/nokogiri/XmlXpathContext.java +3 -3
  18. data/ext/java/nokogiri/internals/HtmlDomParserContext.java +2 -1
  19. data/ext/java/nokogiri/internals/NokogiriHelpers.java +89 -1
  20. data/ext/java/nokogiri/internals/ParserContext.java +23 -2
  21. data/ext/java/nokogiri/internals/SaveContextVisitor.java +18 -1
  22. data/ext/java/nokogiri/internals/XmlDomParserContext.java +2 -3
  23. data/ext/nokogiri/extconf.rb +1 -1
  24. data/ext/nokogiri/xml_io.c +1 -1
  25. data/ext/nokogiri/xml_namespace.c +0 -6
  26. data/ext/nokogiri/xml_node.c +11 -11
  27. data/ext/nokogiri/xml_node_set.c +1 -1
  28. data/ext/nokogiri/xml_xpath_context.c +20 -16
  29. data/ext/nokogiri/xml_xpath_context.h +1 -0
  30. data/ext/nokogiri/xslt_stylesheet.c +7 -64
  31. data/lib/nokogiri/css/node.rb +3 -0
  32. data/lib/nokogiri/css/parser.rb +244 -203
  33. data/lib/nokogiri/css/parser.y +20 -2
  34. data/lib/nokogiri/css/xpath_visitor.rb +2 -2
  35. data/lib/nokogiri/html/document.rb +2 -1
  36. data/lib/nokogiri/html/element_description_defaults.rb +1 -1
  37. data/lib/nokogiri/nokogiri.jar +0 -0
  38. data/lib/nokogiri/version.rb +1 -1
  39. data/lib/nokogiri/xml/document.rb +1 -1
  40. data/lib/nokogiri/xml/parse_options.rb +2 -2
  41. data/lib/nokogiri/xml/sax/document.rb +1 -1
  42. data/lib/nokogiri/xml/sax/parser.rb +1 -1
  43. data/lib/nokogiri/xslt.rb +1 -1
  44. data/test/css/test_parser.rb +38 -0
  45. data/test/files/to_be_xincluded.xml +2 -0
  46. data/test/files/xinclude.xml +4 -0
  47. data/test/helper.rb +18 -45
  48. data/test/html/sax/test_parser.rb +5 -3
  49. data/test/html/sax/test_parser_context.rb +8 -10
  50. data/test/html/test_document.rb +19 -5
  51. data/test/html/test_node.rb +2 -4
  52. data/test/test_reader.rb +63 -0
  53. data/test/test_xslt_transforms.rb +3 -1
  54. data/test/xml/sax/test_parser_context.rb +10 -17
  55. data/test/xml/sax/test_push_parser.rb +1 -0
  56. data/test/xml/test_attr.rb +5 -6
  57. data/test/xml/test_builder.rb +5 -6
  58. data/test/xml/test_cdata.rb +1 -3
  59. data/test/xml/test_document.rb +11 -14
  60. data/test/xml/test_document_encoding.rb +3 -1
  61. data/test/xml/test_document_fragment.rb +27 -8
  62. data/test/xml/test_node.rb +21 -0
  63. data/test/xml/test_node_set.rb +2 -2
  64. data/test/xml/test_text.rb +1 -3
  65. data/test/xml/test_unparented_node.rb +2 -2
  66. data/test/xml/test_xpath.rb +15 -6
  67. data/test/xslt/test_custom_functions.rb +35 -0
  68. data/test_all +84 -0
  69. metadata +13 -8
  70. data/ext/java/nokogiri/internals/PushInputStream.java +0 -411
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * (The MIT License)
3
3
  *
4
- * Copyright (c) 2008 - 2011:
4
+ * Copyright (c) 2008 - 2012:
5
5
  *
6
6
  * * {Aaron Patterson}[http://tenderlovemaking.com]
7
7
  * * {Mike Dalessio}[http://mike.daless.io]
@@ -55,6 +55,7 @@ import org.w3c.dom.NodeList;
55
55
  */
56
56
  @JRubyClass(name="Nokogiri::HTML::Document", parent="Nokogiri::XML::Document")
57
57
  public class HtmlDocument extends XmlDocument {
58
+ private String parsed_encoding = null;
58
59
 
59
60
  public HtmlDocument(Ruby ruby, RubyClass klazz) {
60
61
  super(ruby, klazz);
@@ -123,6 +124,14 @@ public class HtmlDocument extends XmlDocument {
123
124
  stabilzeAttrValue(children.item(i));
124
125
  }
125
126
  }
127
+
128
+ public void setParsedEncoding(String encoding) {
129
+ parsed_encoding = encoding;
130
+ }
131
+
132
+ public String getPraedEncoding() {
133
+ return parsed_encoding;
134
+ }
126
135
 
127
136
  /*
128
137
  * call-seq:
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * (The MIT License)
3
3
  *
4
- * Copyright (c) 2008 - 2011:
4
+ * Copyright (c) 2008 - 2012:
5
5
  *
6
6
  * * {Aaron Patterson}[http://tenderlovemaking.com]
7
7
  * * {Mike Dalessio}[http://mike.daless.io]
@@ -96,6 +96,16 @@ public class XmlAttr extends XmlNode{
96
96
  Node attr = xmlDoc.getDocument().createAttribute(str);
97
97
  setNode(context, attr);
98
98
  }
99
+
100
+
101
+ // this method is called from XmlNode.setNode()
102
+ // if the node is attribute, and its name has prefix "xml"
103
+ // the default namespace should be registered for this attribute
104
+ void setNamespaceIfNecessary(Ruby runtime) {
105
+ if ("xml".equals(node.getPrefix())) {
106
+ XmlNamespace.createDefaultNamespace(runtime, node);
107
+ }
108
+ }
99
109
 
100
110
  private boolean isHtmlBooleanAttr() {
101
111
  String name = node.getNodeName().toLowerCase();
@@ -128,6 +128,10 @@ public class XmlDocument extends XmlNode {
128
128
  this.encoding = encoding;
129
129
  }
130
130
 
131
+ public IRubyObject getEncoding() {
132
+ return encoding;
133
+ }
134
+
131
135
  // not sure, but like attribute values, text value will be lost
132
136
  // unless it is referred once before this document is used.
133
137
  // this seems to happen only when the fragment is parsed from Node#in_context.
@@ -36,6 +36,7 @@ import static nokogiri.internals.NokogiriHelpers.CACHED_NODE;
36
36
  import static nokogiri.internals.NokogiriHelpers.getCachedNodeOrCreate;
37
37
  import static nokogiri.internals.NokogiriHelpers.getLocalNameForNamespace;
38
38
  import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
39
+ import static nokogiri.internals.NokogiriHelpers.stringOrNil;
39
40
  import nokogiri.internals.NokogiriHelpers;
40
41
  import nokogiri.internals.SaveContextVisitor;
41
42
 
@@ -155,6 +156,30 @@ public class XmlNamespace extends RubyObject {
155
156
  return namespace;
156
157
  }
157
158
 
159
+ // owner should be an Attr node
160
+ public static XmlNamespace createDefaultNamespace(Ruby runtime, Node owner) {
161
+ String prefixValue = owner.getPrefix();
162
+ String hrefValue = owner.getNamespaceURI();
163
+ Document document = owner.getOwnerDocument();
164
+ // check namespace cache
165
+ XmlDocument xmlDocument = (XmlDocument)getCachedNodeOrCreate(runtime, document);
166
+ XmlNamespace xmlNamespace = xmlDocument.getNamespaceCache().get(prefixValue, hrefValue);
167
+ if (xmlNamespace != null) return xmlNamespace;
168
+
169
+ // creating XmlNamespace instance
170
+ XmlNamespace namespace =
171
+ (XmlNamespace) NokogiriService.XML_NAMESPACE_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Namespace"));
172
+
173
+ IRubyObject prefix = stringOrNil(runtime, prefixValue);
174
+ IRubyObject href = stringOrNil(runtime, hrefValue);
175
+ // initialize XmlNamespace object
176
+ namespace.init((Attr)owner, prefix, href, prefixValue, hrefValue, xmlDocument);
177
+
178
+ // updating namespace cache
179
+ xmlDocument.getNamespaceCache().put(namespace, owner);
180
+ return namespace;
181
+ }
182
+
158
183
  /**
159
184
  * Create and return a copy of this object.
160
185
  *
@@ -42,13 +42,8 @@ import static nokogiri.internals.NokogiriHelpers.stringOrNil;
42
42
 
43
43
  import java.io.ByteArrayInputStream;
44
44
  import java.io.InputStream;
45
- import java.io.UnsupportedEncodingException;
46
- import java.nio.ByteBuffer;
47
- import java.nio.CharBuffer;
48
45
  import java.nio.charset.CharacterCodingException;
49
46
  import java.nio.charset.Charset;
50
- import java.nio.charset.CharsetDecoder;
51
- import java.nio.charset.CharsetEncoder;
52
47
  import java.util.ArrayList;
53
48
  import java.util.List;
54
49
 
@@ -479,6 +474,10 @@ public class XmlNode extends RubyObject {
479
474
  doc = document(context);
480
475
  }
481
476
  }
477
+
478
+ if (this instanceof XmlAttr) {
479
+ ((XmlAttr)this).setNamespaceIfNecessary(context.getRuntime());
480
+ }
482
481
  }
483
482
 
484
483
  public void updateNodeNamespaceIfNecessary(ThreadContext context, XmlNamespace ns) {
@@ -763,6 +762,7 @@ public class XmlNode extends RubyObject {
763
762
  } else {
764
763
  textContent = this.node.getTextContent();
765
764
  }
765
+ textContent = NokogiriHelpers.convertEncodingByNKFIfNecessary(context.getRuntime(), (XmlDocument)document(context), textContent);
766
766
  String decodedText = null;
767
767
  if (textContent != null) decodedText = NokogiriHelpers.decodeJavaString(textContent);
768
768
  return stringOrNil(context.getRuntime(), decodedText);
@@ -1342,7 +1342,7 @@ public class XmlNode extends RubyObject {
1342
1342
  */
1343
1343
  if (parent.getNodeType() == Node.DOCUMENT_NODE &&
1344
1344
  otherNode.getNodeType() == Node.TEXT_NODE) {
1345
- Element e = ((Document)parent).createElement("text");
1345
+ Element e = ((Document)parent).createElement("nokogiri_text_wrapper");
1346
1346
  e.appendChild(otherNode);
1347
1347
  otherNode = e;
1348
1348
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * (The MIT License)
3
3
  *
4
- * Copyright (c) 2008 - 2011:
4
+ * Copyright (c) 2008 - 2012:
5
5
  *
6
6
  * * {Aaron Patterson}[http://tenderlovemaking.com]
7
7
  * * {Mike Dalessio}[http://mike.daless.io]
@@ -228,8 +228,15 @@ public class XmlReader extends RubyObject {
228
228
  if (!current.hasChildren) return null;
229
229
  StringBuffer sb = new StringBuffer();
230
230
  int currentDepth = (Integer)current.depth;
231
+ int inner = 0;
231
232
  for (ReaderNode node : nodeQueue) {
232
- if (((Integer)node.depth) > currentDepth) sb.append(node.getString());
233
+ if (((Integer)node.depth) == currentDepth && node.getName().equals(current.getName())) {
234
+ inner++;
235
+ }
236
+ if (((Integer)node.depth) > currentDepth) {
237
+ sb.append(node.getString());
238
+ }
239
+ if (inner == 2) break;
233
240
  }
234
241
  return new String(sb);
235
242
  }
@@ -242,9 +249,17 @@ public class XmlReader extends RubyObject {
242
249
  private String getOuterXml(ArrayDeque<ReaderNode> nodeQueue, ReaderNode current) {
243
250
  if (current.depth < 0) return null;
244
251
  StringBuffer sb = new StringBuffer();
245
- int initialDepth = (Integer)current.depth - 1;
252
+ int initialDepth = (Integer)current.depth;
253
+ int inner = 0;
246
254
  for (ReaderNode node : nodeQueue) {
247
- if (((Integer)node.depth) > initialDepth) sb.append(node.getString());
255
+ if (((Integer)node.depth) >= initialDepth) {
256
+ if (((Integer)node.depth) == initialDepth && node.getName().equals(current.getName())) {
257
+ inner++;
258
+ }
259
+
260
+ sb.append(node.getString());
261
+ }
262
+ if (inner == 2) break;
248
263
  }
249
264
  return new String(sb);
250
265
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * (The MIT License)
3
3
  *
4
- * Copyright (c) 2008 - 2011:
4
+ * Copyright (c) 2008 - 2012:
5
5
  *
6
6
  * * {Aaron Patterson}[http://tenderlovemaking.com]
7
7
  * * {Mike Dalessio}[http://mike.daless.io]
@@ -37,10 +37,15 @@ import static org.jruby.javasupport.util.RuntimeHelpers.invoke;
37
37
 
38
38
  import java.io.IOException;
39
39
  import java.io.InputStream;
40
- import java.nio.channels.ClosedChannelException;
40
+ import java.io.OutputStream;
41
+ import java.nio.channels.Channels;
42
+ import java.nio.channels.Pipe;
43
+ import java.util.concurrent.Callable;
44
+ import java.util.concurrent.ExecutorService;
45
+ import java.util.concurrent.Executors;
46
+ import java.util.concurrent.FutureTask;
41
47
 
42
48
  import nokogiri.internals.ParserContext;
43
- import nokogiri.internals.PushInputStream;
44
49
 
45
50
  import org.jruby.Ruby;
46
51
  import org.jruby.RubyClass;
@@ -63,9 +68,12 @@ import org.jruby.runtime.builtin.IRubyObject;
63
68
  public class XmlSaxPushParser extends RubyObject {
64
69
  ParserContext.Options options;
65
70
  IRubyObject optionsRuby;
66
- PushInputStream stream;
67
- Thread reader;
68
- Runner runner;
71
+ IRubyObject saxParser;
72
+ OutputStream ostream = null;
73
+ InputStream istream = null;
74
+ ParserTask parserTask = null;
75
+ FutureTask<XmlSaxParserContext> futureTask = null;
76
+ ExecutorService executor = null;
69
77
 
70
78
  public XmlSaxPushParser(Ruby ruby, RubyClass rubyClass) {
71
79
  super(ruby, rubyClass);
@@ -73,18 +81,12 @@ public class XmlSaxPushParser extends RubyObject {
73
81
 
74
82
  @JRubyMethod
75
83
  public IRubyObject initialize_native(final ThreadContext context,
76
- IRubyObject _saxParser,
84
+ IRubyObject saxParser,
77
85
  IRubyObject fileName) {
78
- optionsRuby = invoke(context,
79
- context.getRuntime().getClassFromPath("Nokogiri::XML::ParseOptions"),
80
- "new");
86
+ optionsRuby
87
+ = invoke(context, context.getRuntime().getClassFromPath("Nokogiri::XML::ParseOptions"), "new");
81
88
  options = new ParserContext.Options(0);
82
- stream = new PushInputStream();
83
-
84
- runner = new Runner(context, this, stream);
85
- reader = new Thread(runner);
86
- reader.start();
87
-
89
+ this.saxParser = saxParser;
88
90
  return this;
89
91
  }
90
92
 
@@ -110,74 +112,103 @@ public class XmlSaxPushParser extends RubyObject {
110
112
  @JRubyMethod
111
113
  public IRubyObject native_write(ThreadContext context, IRubyObject chunk,
112
114
  IRubyObject isLast) {
115
+ try {
116
+ initialize_task(context);
117
+ } catch (IOException e) {
118
+ throw context.getRuntime().newRuntimeError(e.getMessage());
119
+ }
113
120
  byte[] data = null;
114
121
  if (chunk instanceof RubyString || chunk.respondsTo("to_str")) {
115
122
  data = chunk.convertToString().getBytes();
116
- } else {
117
- XmlSyntaxError xmlSyntaxError = (XmlSyntaxError) NokogiriService.XML_SYNTAXERROR_ALLOCATOR.allocate(context.getRuntime(), getNokogiriClass(context.getRuntime(), "Nokogiri::XML::SyntaxError"));
123
+ } else {
124
+ try {
125
+ terminateTask();
126
+ } catch (IOException e) {
127
+ throw context.getRuntime().newRuntimeError(e.getMessage());
128
+ }
129
+ XmlSyntaxError xmlSyntaxError =
130
+ (XmlSyntaxError) NokogiriService.XML_SYNTAXERROR_ALLOCATOR.allocate(context.getRuntime(), getNokogiriClass(context.getRuntime(), "Nokogiri::XML::SyntaxError"));
118
131
  throw new RaiseException(xmlSyntaxError);
119
132
  }
120
133
 
121
- int errorCount0 = runner.getErrorCount();
122
-
134
+ int errorCount0 = parserTask.getErrorCount();;
135
+
123
136
  try {
124
- stream.writeAndWaitForRead(data);
125
- } catch (ClosedChannelException e) {
126
- // ignore
137
+ if (isLast.isTrue()) {
138
+ IRubyObject document = invoke(context, this, "document");
139
+ invoke(context, document, "end_document");
140
+ terminateTask();
141
+ } else {
142
+ ostream.write(data);
143
+ Thread.currentThread().sleep(10); // gives a reader a chance to work
144
+ }
127
145
  } catch (IOException e) {
128
- throw context.getRuntime().newRuntimeError(e.toString());
146
+ throw context.getRuntime().newRuntimeError(e.getMessage());
147
+ } catch (InterruptedException e) {
148
+ throw context.getRuntime().newRuntimeError(e.getMessage());
129
149
  }
130
150
 
131
- if (isLast.isTrue()) {
151
+ if (!options.recover && parserTask.getErrorCount() > errorCount0) {
132
152
  try {
133
- stream.close();
153
+ terminateTask();
134
154
  } catch (IOException e) {
135
- // ignore
136
- }
137
-
138
- for (;;) {
139
- try {
140
- reader.join();
141
- break;
142
- } catch (InterruptedException e) {
143
- // continue loop
144
- }
155
+ throw context.getRuntime().newRuntimeError(e.getMessage());
145
156
  }
146
- }
147
-
148
- if (!options.recover && runner.getErrorCount() > errorCount0) {
149
- throw new RaiseException(runner.getLastError(), true);
157
+ throw new RaiseException(parserTask.getLastError(), true);
150
158
  }
151
159
 
152
160
  return this;
153
161
  }
154
-
155
- protected static class Runner implements Runnable {
156
- protected ThreadContext context;
157
- protected IRubyObject handler;
158
- protected XmlSaxParserContext parser;
159
-
160
- public Runner(ThreadContext context,
161
- IRubyObject handler,
162
- InputStream stream) {
162
+
163
+ private void initialize_task(ThreadContext context) throws IOException {
164
+ if (futureTask == null || ostream == null || istream == null) {
165
+ Pipe pipe = Pipe.open();
166
+ Pipe.SinkChannel sink = pipe.sink();
167
+ ostream = Channels.newOutputStream(sink);
168
+ Pipe.SourceChannel source = pipe.source();
169
+ istream = Channels.newInputStream(source);
170
+
171
+ parserTask = new ParserTask(context, saxParser);
172
+ futureTask = new FutureTask<XmlSaxParserContext>(parserTask);
173
+ executor = Executors.newSingleThreadExecutor();
174
+ executor.submit(futureTask);
175
+ }
176
+ }
177
+
178
+ private synchronized void terminateTask() throws IOException {
179
+ futureTask.cancel(true);
180
+ executor.shutdown();
181
+ ostream.close();
182
+ istream.close();
183
+ ostream = null;
184
+ istream = null;
185
+ }
186
+
187
+ private class ParserTask implements Callable<XmlSaxParserContext> {
188
+ private ThreadContext context;
189
+ private IRubyObject handler;
190
+ private XmlSaxParserContext parser;
191
+
192
+ private ParserTask(ThreadContext context, IRubyObject handler) {
163
193
  RubyClass klazz = getNokogiriClass(context.getRuntime(), "Nokogiri::XML::SAX::ParserContext");
164
-
165
194
  this.context = context;
166
195
  this.handler = handler;
167
- this.parser = (XmlSaxParserContext) XmlSaxParserContext.parse_stream(context, klazz, stream);
196
+ this.parser = (XmlSaxParserContext) XmlSaxParserContext.parse_stream(context, klazz, istream);
168
197
  }
169
198
 
170
- public void run() {
199
+ @Override
200
+ public XmlSaxParserContext call() throws Exception {
171
201
  parser.parse_with(context, handler);
202
+ return parser;
172
203
  }
173
-
174
- public int getErrorCount() {
175
- // check for null because thread may nto have started yet
204
+
205
+ private synchronized int getErrorCount() {
206
+ // check for null because thread may not have started yet
176
207
  if (parser.getNokogiriHandler() == null) return 0;
177
208
  else return parser.getNokogiriHandler().getErrorCount();
178
209
  }
179
-
180
- public RubyException getLastError() {
210
+
211
+ private synchronized RubyException getLastError() {
181
212
  return (RubyException) parser.getNokogiriHandler().getLastError();
182
213
  }
183
214
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * (The MIT License)
3
3
  *
4
- * Copyright (c) 2008 - 2011:
4
+ * Copyright (c) 2008 - 2012:
5
5
  *
6
6
  * * {Aaron Patterson}[http://tenderlovemaking.com]
7
7
  * * {Mike Dalessio}[http://mike.daless.io]
@@ -35,6 +35,7 @@ package nokogiri;
35
35
  import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
36
36
  import static nokogiri.internals.NokogiriHelpers.stringOrNil;
37
37
 
38
+ import org.jruby.CompatVersion;
38
39
  import org.jruby.Ruby;
39
40
  import org.jruby.RubyClass;
40
41
  import org.jruby.RubyException;
@@ -108,12 +109,23 @@ public class XmlSyntaxError extends RubyException {
108
109
  return new XmlSyntaxError(runtime, klazz, e);
109
110
  }
110
111
 
111
- @Override
112
- @JRubyMethod(name = "to_s")
112
+ //@Override
113
+ //"to_s" method was branched in 1.8 and 1.9 since JRuby 1.6.6
114
+ // to support older version of JRuby, the annotation is commented out
115
+ @JRubyMethod(name = "to_s", compat = CompatVersion.RUBY1_8)
113
116
  public IRubyObject to_s(ThreadContext context) {
114
117
  if (exception != null && exception.getMessage() != null)
115
118
  return context.getRuntime().newString(exception.getMessage());
116
119
  else
117
120
  return super.to_s(context);
118
121
  }
122
+
123
+ //@Override
124
+ //"to_s" method was branched in 1.8 and 1.9 since JRuby 1.6.6
125
+ // to support older version of JRuby, the annotation is commented out
126
+ @JRubyMethod(name = "to_s", compat = CompatVersion.RUBY1_9)
127
+ public IRubyObject to_s19(ThreadContext context) {
128
+ return this.to_s(context);
129
+ }
130
+
119
131
  }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * (The MIT License)
3
3
  *
4
- * Copyright (c) 2008 - 2011:
4
+ * Copyright (c) 2008 - 2012:
5
5
  *
6
6
  * * {Aaron Patterson}[http://tenderlovemaking.com]
7
7
  * * {Mike Dalessio}[http://mike.daless.io]
@@ -53,7 +53,6 @@ import org.jruby.RubyBoolean;
53
53
  import org.jruby.RubyClass;
54
54
  import org.jruby.RubyException;
55
55
  import org.jruby.RubyFloat;
56
- import org.jruby.RubyNumeric;
57
56
  import org.jruby.RubyObject;
58
57
  import org.jruby.RubyString;
59
58
  import org.jruby.anno.JRubyClass;
@@ -72,7 +71,7 @@ import org.w3c.dom.NodeList;
72
71
  @JRubyClass(name="Nokogiri::XML::XPathContext")
73
72
  public class XmlXpathContext extends RubyObject {
74
73
  private XmlNode context;
75
- private static final XPath xpath = XPathFactory.newInstance().newXPath();;
74
+ private XPath xpath;
76
75
 
77
76
  public XmlXpathContext(Ruby ruby, RubyClass rubyClass) {
78
77
  super(ruby, rubyClass);
@@ -98,6 +97,7 @@ public class XmlXpathContext extends RubyObject {
98
97
  public static IRubyObject rbNew(ThreadContext context, IRubyObject klazz, IRubyObject node) {
99
98
  XmlNode xmlNode = (XmlNode)node;
100
99
  XmlXpathContext xmlXpathContext = (XmlXpathContext) NokogiriService.XML_XPATHCONTEXT_ALLOCATOR.allocate(context.getRuntime(), (RubyClass)klazz);
100
+ xmlXpathContext.xpath = XPathFactory.newInstance().newXPath();
101
101
  xmlXpathContext.setNode(xmlNode);
102
102
  return xmlXpathContext;
103
103
  }