nokogiri 1.5.0.beta.4-java → 1.5.0-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 (87) hide show
  1. data/.gemtest +0 -0
  2. data/CHANGELOG.ja.rdoc +34 -0
  3. data/CHANGELOG.rdoc +40 -1
  4. data/Manifest.txt +11 -2
  5. data/README.rdoc +1 -1
  6. data/Rakefile +96 -105
  7. data/bin/nokogiri +1 -2
  8. data/ext/java/nokogiri/HtmlDocument.java +1 -31
  9. data/ext/java/nokogiri/HtmlSaxParserContext.java +1 -1
  10. data/ext/java/nokogiri/NokogiriService.java +77 -22
  11. data/ext/java/nokogiri/XmlAttr.java +5 -16
  12. data/ext/java/nokogiri/XmlCdata.java +4 -11
  13. data/ext/java/nokogiri/XmlComment.java +5 -5
  14. data/ext/java/nokogiri/XmlDocument.java +49 -59
  15. data/ext/java/nokogiri/XmlDocumentFragment.java +14 -8
  16. data/ext/java/nokogiri/XmlDtd.java +45 -43
  17. data/ext/java/nokogiri/XmlElement.java +19 -46
  18. data/ext/java/nokogiri/XmlElementDecl.java +9 -5
  19. data/ext/java/nokogiri/XmlEntityReference.java +24 -2
  20. data/ext/java/nokogiri/XmlNamespace.java +89 -34
  21. data/ext/java/nokogiri/XmlNode.java +31 -52
  22. data/ext/java/nokogiri/XmlNodeSet.java +42 -86
  23. data/ext/java/nokogiri/XmlProcessingInstruction.java +15 -19
  24. data/ext/java/nokogiri/XmlReader.java +40 -43
  25. data/ext/java/nokogiri/XmlSaxParserContext.java +2 -2
  26. data/ext/java/nokogiri/XmlSchema.java +14 -9
  27. data/ext/java/nokogiri/XmlText.java +18 -35
  28. data/ext/java/nokogiri/XmlXpathContext.java +43 -23
  29. data/ext/java/nokogiri/XsltStylesheet.java +17 -3
  30. data/ext/java/nokogiri/internals/HtmlDomParserContext.java +2 -4
  31. data/ext/java/nokogiri/internals/NokogiriHelpers.java +77 -20
  32. data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +13 -17
  33. data/ext/java/nokogiri/internals/NokogiriNamespaceContext.java +13 -1
  34. data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +23 -8
  35. data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +20 -3
  36. data/ext/java/nokogiri/internals/NokogiriXPathVariableResolver.java +67 -0
  37. data/ext/java/nokogiri/internals/NokogiriXsltErrorListener.java +86 -0
  38. data/ext/java/nokogiri/internals/ParserContext.java +25 -27
  39. data/ext/java/nokogiri/internals/ReaderNode.java +58 -1
  40. data/ext/java/nokogiri/internals/SaveContextVisitor.java +567 -0
  41. data/ext/java/nokogiri/internals/XmlDomParser.java +1 -2
  42. data/ext/java/nokogiri/internals/XmlDomParserContext.java +6 -0
  43. data/ext/nokogiri/nokogiri.c +24 -1
  44. data/ext/nokogiri/xml_io.c +32 -7
  45. data/ext/nokogiri/xml_node.c +14 -13
  46. data/ext/nokogiri/xml_sax_parser.c +9 -4
  47. data/ext/nokogiri/xslt_stylesheet.c +7 -1
  48. data/lib/nokogiri.rb +3 -22
  49. data/lib/nokogiri/css.rb +4 -0
  50. data/lib/nokogiri/html/document.rb +10 -14
  51. data/lib/nokogiri/nokogiri.jar +0 -0
  52. data/lib/nokogiri/version.rb +76 -23
  53. data/lib/nokogiri/xml/builder.rb +7 -0
  54. data/lib/nokogiri/xml/document.rb +17 -1
  55. data/lib/nokogiri/xml/document_fragment.rb +14 -0
  56. data/lib/nokogiri/xml/node.rb +36 -28
  57. data/lib/nokogiri/xml/node/save_options.rb +17 -1
  58. data/lib/nokogiri/xml/node_set.rb +7 -0
  59. data/lib/nokogiri/xml/parse_options.rb +8 -0
  60. data/lib/nokogiri/xml/reader.rb +6 -6
  61. data/lib/nokogiri/xml/schema.rb +7 -1
  62. data/lib/xercesImpl.jar +0 -0
  63. data/nokogiri_help_responses.md +40 -0
  64. data/tasks/cross_compile.rb +134 -159
  65. data/tasks/nokogiri.org.rb +18 -0
  66. data/tasks/test.rb +1 -1
  67. data/test/files/encoding.html +82 -0
  68. data/test/files/encoding.xhtml +84 -0
  69. data/test/files/metacharset.html +10 -0
  70. data/test/files/noencoding.html +47 -0
  71. data/test/helper.rb +2 -0
  72. data/test/html/test_document.rb +15 -0
  73. data/test/html/test_document_encoding.rb +13 -0
  74. data/test/test_memory_leak.rb +20 -0
  75. data/test/test_reader.rb +22 -0
  76. data/test/test_xslt_transforms.rb +6 -2
  77. data/test/xml/node/test_save_options.rb +10 -2
  78. data/test/xml/test_builder.rb +17 -0
  79. data/test/xml/test_document.rb +22 -0
  80. data/test/xml/test_node.rb +19 -1
  81. data/test/xml/test_node_reparenting.rb +16 -3
  82. data/test/xml/test_node_set.rb +34 -0
  83. data/test/xml/test_schema.rb +5 -0
  84. data/test/xslt/test_exception_handling.rb +37 -0
  85. metadata +141 -107
  86. data/deps.rip +0 -5
  87. data/ext/java/nokogiri/internals/SaveContext.java +0 -288
@@ -32,6 +32,7 @@
32
32
 
33
33
  package nokogiri;
34
34
 
35
+ import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
35
36
  import static nokogiri.internals.NokogiriHelpers.stringOrBlank;
36
37
 
37
38
  import java.io.ByteArrayInputStream;
@@ -47,14 +48,12 @@ import org.jruby.RubyArray;
47
48
  import org.jruby.RubyBoolean;
48
49
  import org.jruby.RubyClass;
49
50
  import org.jruby.RubyFixnum;
50
- import org.jruby.RubyModule;
51
51
  import org.jruby.RubyObject;
52
52
  import org.jruby.RubyString;
53
53
  import org.jruby.anno.JRubyClass;
54
54
  import org.jruby.anno.JRubyMethod;
55
55
  import org.jruby.exceptions.RaiseException;
56
56
  import org.jruby.javasupport.util.RuntimeHelpers;
57
- import org.jruby.runtime.Block;
58
57
  import org.jruby.runtime.ThreadContext;
59
58
  import org.jruby.runtime.builtin.IRubyObject;
60
59
  import org.jruby.util.ByteList;
@@ -82,20 +81,26 @@ public class XmlReader extends RubyObject {
82
81
  private static final int XML_TEXTREADER_MODE_CLOSED = 4;
83
82
  private static final int XML_TEXTREADER_MODE_READING = 5;
84
83
 
85
- final ArrayDeque<ReaderNode> nodeQueue = new ArrayDeque<ReaderNode>();
84
+ ArrayDeque<ReaderNode> nodeQueue;
86
85
  private int state;
87
86
 
88
- public XmlReader(Ruby ruby, RubyClass rubyClass) {
89
- super(ruby, rubyClass);
90
- nodeQueue.add(new ReaderNode.EmptyNode(ruby));
87
+ public XmlReader(Ruby runtime, RubyClass klazz) {
88
+ super(runtime, klazz);
91
89
  }
92
-
93
- private static IRubyObject[] getArgs(IRubyObject[] args) {
94
- int size = Math.min(args.length, 3);
95
- IRubyObject[] newArgs = new IRubyObject[size];
96
- for(int i = 0; i < size; i++)
97
- newArgs[i] = args[i];
98
- return newArgs;
90
+
91
+ /**
92
+ * Create and return a copy of this object.
93
+ *
94
+ * @return a clone of this object
95
+ */
96
+ @Override
97
+ public Object clone() throws CloneNotSupportedException {
98
+ return super.clone();
99
+ }
100
+
101
+ public void init(Ruby runtime) {
102
+ nodeQueue = new ArrayDeque<ReaderNode>();
103
+ nodeQueue.add(new ReaderNode.EmptyNode(runtime));
99
104
  }
100
105
 
101
106
  private void parseRubyString(ThreadContext context, RubyString content){
@@ -117,10 +122,6 @@ public class XmlReader extends RubyObject {
117
122
  }
118
123
  }
119
124
 
120
- private void setSource(IRubyObject source){
121
- this.setInstanceVariable("@source", source);
122
- }
123
-
124
125
  private void setState(int state) { this.state = state; }
125
126
 
126
127
  @JRubyMethod
@@ -178,41 +179,37 @@ public class XmlReader extends RubyObject {
178
179
 
179
180
  @JRubyMethod(meta = true, rest = true)
180
181
  public static IRubyObject from_io(ThreadContext context, IRubyObject cls, IRubyObject args[]) {
181
-
182
182
  // Only to pass the source test.
183
- Ruby ruby = context.getRuntime();
184
-
183
+ Ruby runtime = context.getRuntime();
185
184
  // Not nil allowed!
186
- if(args[0].isNil()) throw ruby.newArgumentError("io cannot be nil");
187
-
188
- XmlReader r = new XmlReader(ruby, ((RubyModule) ruby.getModule("Nokogiri").getConstant("XML")).getClass("Reader"));
185
+ if(args[0].isNil()) throw runtime.newArgumentError("io cannot be nil");
189
186
 
190
- r.callInit(getArgs(args), Block.NULL_BLOCK);
187
+ XmlReader reader = (XmlReader) NokogiriService.XML_READER_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Reader"));
188
+ reader.init(runtime);
189
+ reader.setInstanceVariable("@source", args[0]);
190
+ reader.setInstanceVariable("@errors", runtime.newArray());
191
+ if (args.length > 2) reader.setInstanceVariable("@encoding", args[2]);
191
192
 
192
- r.setSource(args[0]);
193
-
194
193
  RubyString content = RuntimeHelpers.invoke(context, args[0], "read").convertToString();
195
-
196
- r.parseRubyString(context, content);
197
- return r;
194
+ reader.parseRubyString(context, content);
195
+ return reader;
198
196
  }
199
197
 
200
198
  @JRubyMethod(meta = true, rest = true)
201
199
  public static IRubyObject from_memory(ThreadContext context, IRubyObject cls, IRubyObject args[]) {
202
- Ruby ruby = context.getRuntime();
203
-
200
+ // args[0]: string, args[1]: url, args[2]: encoding, args[3]: options
201
+ Ruby runtime = context.getRuntime();
204
202
  // Not nil allowed!
205
- if(args[0].isNil()) throw ruby.newArgumentError("string cannot be nil");
206
-
207
- XmlReader r = new XmlReader(ruby, ((RubyModule) ruby.getModule("Nokogiri").getConstant("XML")).getClass("Reader"));
208
-
209
- r.callInit(getArgs(args), Block.NULL_BLOCK);
210
-
211
- r.setSource(args[0]);
203
+ if(args[0].isNil()) throw runtime.newArgumentError("string cannot be nil");
212
204
 
213
- r.parseRubyString(context, args[0].convertToString());
205
+ XmlReader reader = (XmlReader) NokogiriService.XML_READER_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Reader"));
206
+ reader.init(runtime);
207
+ reader.setInstanceVariable("@source", args[0]);
208
+ reader.setInstanceVariable("@errors", runtime.newArray());
209
+ if (args.length > 2) reader.setInstanceVariable("@encoding", args[2]);
214
210
 
215
- return r;
211
+ reader.parseRubyString(context, args[0].convertToString());
212
+ return reader;
216
213
  }
217
214
 
218
215
  @JRubyMethod
@@ -329,7 +326,7 @@ public class XmlReader extends RubyObject {
329
326
 
330
327
  @Override
331
328
  public void characters(char[] chars, int start, int length) {
332
- ReaderNode.TextNode node = new ReaderNode.TextNode(ruby, new String(chars, start, length), depth, langStack, xmlBaseStack);
329
+ ReaderNode.TextNode node = ReaderNode.createTextNode(ruby, new String(chars, start, length), depth, langStack, xmlBaseStack);
333
330
  nodeQueue.add(node);
334
331
  }
335
332
 
@@ -348,7 +345,7 @@ public class XmlReader extends RubyObject {
348
345
  if (previous instanceof ReaderNode.ElementNode && qName.equals(previous.name)) {
349
346
  previous.hasChildren = false;
350
347
  } else {
351
- ReaderNode node = new ReaderNode.ClosingNode(ruby, uri, localName, qName, depth, langStack, xmlBaseStack);
348
+ ReaderNode node = ReaderNode.createClosingNode(ruby, uri, localName, qName, depth, langStack, xmlBaseStack);
352
349
  if (startElementNode != null) {
353
350
  node.attributeList = startElementNode.attributeList;
354
351
  node.namespaces = startElementNode.namespaces;
@@ -381,7 +378,7 @@ public class XmlReader extends RubyObject {
381
378
 
382
379
  @Override
383
380
  public void startElement(String uri, String localName, String qName, Attributes attrs) {
384
- ReaderNode readerNode = new ReaderNode.ElementNode(ruby, uri, localName, qName, attrs, depth, langStack, xmlBaseStack);
381
+ ReaderNode readerNode = ReaderNode.createElementNode(ruby, uri, localName, qName, attrs, depth, langStack, xmlBaseStack);
385
382
  nodeQueue.add(readerNode);
386
383
  depth++;
387
384
  if (readerNode.lang != null) langStack.push(readerNode.lang);
@@ -121,7 +121,7 @@ public class XmlSaxParserContext extends ParserContext {
121
121
  IRubyObject data) {
122
122
  XmlSaxParserContext ctx = (XmlSaxParserContext) NokogiriService.XML_SAXPARSER_CONTEXT_ALLOCATOR.allocate(context.getRuntime(), (RubyClass) klazz);
123
123
  ctx.initialize(context.getRuntime());
124
- ctx.setInputSource(context, data);
124
+ ctx.setInputSource(context, data, context.getRuntime().getNil());
125
125
  return ctx;
126
126
  }
127
127
 
@@ -153,7 +153,7 @@ public class XmlSaxParserContext extends ParserContext {
153
153
  //int encoding = (int)enc.convertToInteger().getLongValue();
154
154
  XmlSaxParserContext ctx = (XmlSaxParserContext) NokogiriService.XML_SAXPARSER_CONTEXT_ALLOCATOR.allocate(context.getRuntime(), (RubyClass) klazz);
155
155
  ctx.initialize(context.getRuntime());
156
- ctx.setInputSource(context, data);
156
+ ctx.setInputSource(context, data, context.getRuntime().getNil());
157
157
  return ctx;
158
158
  }
159
159
 
@@ -33,6 +33,7 @@
33
33
  package nokogiri;
34
34
 
35
35
  import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
36
+ import static nokogiri.internals.NokogiriHelpers.adjustSystemIdIfNecessary;
36
37
 
37
38
  import java.io.IOException;
38
39
  import java.io.InputStream;
@@ -91,9 +92,9 @@ public class XmlSchema extends RubyObject {
91
92
  return super.clone();
92
93
  }
93
94
 
94
- private Schema getSchema(Source source, String currentDir) throws SAXException {
95
+ private Schema getSchema(Source source, String currentDir, String scriptFileName) throws SAXException {
95
96
  SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
96
- SchemaResourceResolver resourceResolver = new SchemaResourceResolver(currentDir, null);
97
+ SchemaResourceResolver resourceResolver = new SchemaResourceResolver(currentDir, scriptFileName, null);
97
98
  schemaFactory.setResourceResolver(resourceResolver);
98
99
  return schemaFactory.newSchema(source);
99
100
  }
@@ -108,7 +109,7 @@ public class XmlSchema extends RubyObject {
108
109
  xmlSchema.setInstanceVariable("@errors", runtime.newEmptyArray());
109
110
 
110
111
  try {
111
- Schema schema = xmlSchema.getSchema(source, context.getRuntime().getCurrentDirectory());
112
+ Schema schema = xmlSchema.getSchema(source, context.getRuntime().getCurrentDirectory(), context.getRuntime().getInstanceConfig().getScriptFileName());
112
113
  xmlSchema.setValidator(schema.newValidator());
113
114
  return xmlSchema;
114
115
  } catch (SAXException ex) {
@@ -168,7 +169,7 @@ public class XmlSchema extends RubyObject {
168
169
  Ruby ruby = context.getRuntime();
169
170
 
170
171
  XmlDomParserContext ctx = new XmlDomParserContext(ruby, RubyFixnum.newFixnum(ruby, 1L));
171
- ctx.setInputSource(context, file);
172
+ ctx.setInputSource(context, file, context.getRuntime().getNil());
172
173
  XmlDocument xmlDocument = ctx.parse(context, getNokogiriClass(ruby, "Nokogiri::XML::Document"), ruby.getNil());
173
174
  return validate_document_or_file(context, xmlDocument);
174
175
  }
@@ -202,10 +203,13 @@ public class XmlSchema extends RubyObject {
202
203
 
203
204
  private class SchemaResourceResolver implements LSResourceResolver {
204
205
  SchemaLSInput lsInput = new SchemaLSInput();
205
- String defaultURI;
206
+ String currentDir;
207
+ String scriptFileName;
208
+ //String defaultURI;
206
209
 
207
- SchemaResourceResolver(String currentDir, Object input) {
208
- defaultURI = currentDir + "/nokogiri_default_fake.xsd";
210
+ SchemaResourceResolver(String currentDir, String scriptFileName, Object input) {
211
+ this.currentDir = currentDir;
212
+ this.scriptFileName = scriptFileName;
209
213
  if (input == null) return;
210
214
  if (input instanceof String) {
211
215
  lsInput.setStringData((String)input);
@@ -218,9 +222,10 @@ public class XmlSchema extends RubyObject {
218
222
 
219
223
  @Override
220
224
  public LSInput resolveResource(String type, String namespaceURI, String publicId, String systemId, String baseURI) {
225
+ String adjusted = adjustSystemIdIfNecessary(currentDir, scriptFileName, baseURI, systemId);
221
226
  lsInput.setPublicId(publicId);
222
- lsInput.setSystemId(systemId);
223
- lsInput.setBaseURI(baseURI != null ? baseURI : defaultURI);
227
+ lsInput.setSystemId(adjusted);
228
+ lsInput.setBaseURI(baseURI);
224
229
  return lsInput;
225
230
  }
226
231
  }
@@ -32,11 +32,10 @@
32
32
 
33
33
  package nokogiri;
34
34
 
35
- import static nokogiri.internals.NokogiriHelpers.isXmlEscaped;
35
+ import static nokogiri.internals.NokogiriHelpers.getCachedNodeOrCreate;
36
36
  import static nokogiri.internals.NokogiriHelpers.rubyStringToString;
37
37
  import static nokogiri.internals.NokogiriHelpers.stringOrNil;
38
- import nokogiri.internals.NokogiriHelpers;
39
- import nokogiri.internals.SaveContext;
38
+ import nokogiri.internals.SaveContextVisitor;
40
39
 
41
40
  import org.jruby.Ruby;
42
41
  import org.jruby.RubyClass;
@@ -46,6 +45,7 @@ import org.jruby.runtime.ThreadContext;
46
45
  import org.jruby.runtime.builtin.IRubyObject;
47
46
  import org.w3c.dom.Document;
48
47
  import org.w3c.dom.Node;
48
+ import org.w3c.dom.Text;
49
49
 
50
50
  /**
51
51
  * Class for Nokogiri::XML::Text
@@ -98,39 +98,22 @@ public class XmlText extends XmlNode {
98
98
  return content;
99
99
  }
100
100
  }
101
-
102
- @Override
103
- public void saveContent(ThreadContext context, SaveContext ctx) {
104
- String textContent = node.getTextContent();
105
-
106
- if (!isXmlEscaped(textContent)) {
107
- textContent = NokogiriHelpers.encodeJavaString(textContent);
108
- }
109
- if (getEncoding(context, ctx) == null) {
110
- textContent = encodeStringToHtmlEntity(textContent);
111
- }
112
- ctx.append(textContent);
113
- }
114
101
 
115
- private String getEncoding(ThreadContext context, SaveContext ctx) {
116
- String encoding = ctx.getEncoding();
117
- if (encoding != null) return encoding;
118
- XmlDocument xmlDocument = (XmlDocument)document(context);
119
- IRubyObject ruby_encoding = xmlDocument.encoding(context);
120
- if (!ruby_encoding.isNil()) {
121
- encoding = rubyStringToString(ruby_encoding);
122
- }
123
- return encoding;
124
- }
125
-
126
- private String encodeStringToHtmlEntity(String text) {
127
- int last = 126; // = U+007E. No need to encode under U+007E.
128
- StringBuffer sb = new StringBuffer();
129
- for (int i=0; i<text.length(); i++) {
130
- int codePoint = text.codePointAt(i);
131
- if (codePoint > last) sb.append("&#x" + Integer.toHexString(codePoint) + ";");
132
- else sb.append(text.charAt(i));
102
+ @Override
103
+ public void accept(ThreadContext context, SaveContextVisitor visitor) {
104
+ visitor.enter((Text)node);
105
+ Node child = node.getFirstChild();
106
+ while (child != null) {
107
+ IRubyObject nokoNode = getCachedNodeOrCreate(context.getRuntime(), child);
108
+ if (nokoNode instanceof XmlNode) {
109
+ XmlNode cur = (XmlNode) nokoNode;
110
+ cur.accept(context, visitor);
111
+ } else if (nokoNode instanceof XmlNamespace) {
112
+ XmlNamespace cur = (XmlNamespace) nokoNode;
113
+ cur.accept(context, visitor);
114
+ }
115
+ child = child.getNextSibling();
133
116
  }
134
- return new String(sb);
117
+ visitor.leave((Text)node);
135
118
  }
136
119
  }
@@ -71,25 +71,39 @@ import org.w3c.dom.NodeList;
71
71
  @JRubyClass(name="Nokogiri::XML::XPathContext")
72
72
  public class XmlXpathContext extends RubyObject {
73
73
  private XmlNode context;
74
- private XPath xpath;
75
-
76
- public XmlXpathContext(Ruby ruby, RubyClass rubyClass, XmlNode context) {
74
+ private static final XPath xpath = XPathFactory.newInstance().newXPath();;
75
+
76
+ public XmlXpathContext(Ruby ruby, RubyClass rubyClass) {
77
77
  super(ruby, rubyClass);
78
- this.context = context;
79
- this.xpath = XPathFactory.newInstance().newXPath();
80
- this.xpath.setNamespaceContext(new NokogiriNamespaceContext());
81
- this.xpath.setXPathVariableResolver(new NokogiriXPathVariableResolver());
78
+ }
79
+
80
+ public void setNode(XmlNode node) {
81
+ context = node;
82
+ xpath.setNamespaceContext(NokogiriNamespaceContext.create());
83
+ xpath.setXPathVariableResolver(NokogiriXPathVariableResolver.create());
84
+ }
85
+
86
+ /**
87
+ * Create and return a copy of this object.
88
+ *
89
+ * @return a clone of this object
90
+ */
91
+ @Override
92
+ public Object clone() throws CloneNotSupportedException {
93
+ return super.clone();
82
94
  }
83
95
 
84
96
  @JRubyMethod(name = "new", meta = true)
85
- public static IRubyObject rbNew(ThreadContext context, IRubyObject cls, IRubyObject node) {
97
+ public static IRubyObject rbNew(ThreadContext context, IRubyObject klazz, IRubyObject node) {
86
98
  XmlNode xmlNode = (XmlNode)node;
87
- return new XmlXpathContext(context.getRuntime(), (RubyClass)cls, xmlNode);
99
+ XmlXpathContext xmlXpathContext = (XmlXpathContext) NokogiriService.XML_XPATHCONTEXT_ALLOCATOR.allocate(context.getRuntime(), (RubyClass)klazz);
100
+ xmlXpathContext.setNode(xmlNode);
101
+ return xmlXpathContext;
88
102
  }
89
103
 
90
104
  @JRubyMethod
91
105
  public IRubyObject evaluate(ThreadContext context, IRubyObject expr, IRubyObject handler) {
92
- String src = expr.convertToString().asJavaString();
106
+ String src = (String) expr.toJava(String.class);
93
107
  try {
94
108
  if(!handler.isNil()) {
95
109
  if (!isContainsPrefix(src)) {
@@ -98,14 +112,13 @@ public class XmlXpathContext extends RubyObject {
98
112
  src = src.replaceAll(name, NokogiriNamespaceContext.NOKOGIRI_PREFIX+":"+name);
99
113
  }
100
114
  }
101
- xpath.setXPathFunctionResolver(new NokogiriXPathFunctionResolver(handler));
115
+ xpath.setXPathFunctionResolver(NokogiriXPathFunctionResolver.create(handler));
102
116
  }
103
117
  XPathExpression xpathExpression = xpath.compile(src);
104
118
  return node_set(context, xpathExpression);
105
119
  } catch (XPathExpressionException xpee) {
106
120
  xpee = new XPathExpressionException(src);
107
- RubyException e =
108
- XmlSyntaxError.createXPathSyntaxError(getRuntime(), xpee);
121
+ RubyException e = XmlSyntaxError.createXPathSyntaxError(getRuntime(), xpee);
109
122
  throw new RaiseException(e);
110
123
  }
111
124
  }
@@ -114,7 +127,6 @@ public class XmlXpathContext extends RubyObject {
114
127
  XmlNodeSet result = null;
115
128
  try {
116
129
  result = tryGetNodeSet(xpathExpression);
117
- result.setDocument(context.document(rbctx));
118
130
  return result;
119
131
  } catch (XPathExpressionException xpee) {
120
132
  try {
@@ -127,22 +139,30 @@ public class XmlXpathContext extends RubyObject {
127
139
  }
128
140
 
129
141
  private XmlNodeSet tryGetNodeSet(XPathExpression xpathExpression) throws XPathExpressionException {
130
- NodeList nodes = (NodeList)xpathExpression.evaluate(context.node, XPathConstants.NODESET);
142
+ NodeList nodeList = (NodeList)xpathExpression.evaluate(context.node, XPathConstants.NODESET);
131
143
  XmlNodeSet xmlNodeSet = (XmlNodeSet) NokogiriService.XML_NODESET_ALLOCATOR.allocate(getRuntime(), getNokogiriClass(getRuntime(), "Nokogiri::XML::NodeSet"));
132
- xmlNodeSet.setNodeList(nodes);
144
+ xmlNodeSet.setNodeList(nodeList);
133
145
  return xmlNodeSet;
134
146
  }
135
-
136
- private static Pattern number_pattern = Pattern.compile("\\d.*");
147
+
137
148
  private static Pattern boolean_pattern = Pattern.compile("true|false");
138
149
 
139
150
  private IRubyObject tryGetOpaqueValue(XPathExpression xpathExpression) throws XPathExpressionException {
140
151
  String string = (String)xpathExpression.evaluate(context.node, XPathConstants.STRING);
141
- if (doesMatch(number_pattern, string)) return RubyNumeric.dbl2num(getRuntime(), Double.parseDouble(string));
142
- if (doesMatch(boolean_pattern, string)) return RubyBoolean.newBoolean(getRuntime(), Boolean.parseBoolean(string));
152
+ Double value = null;
153
+ if ((value = getDoubleValue(string)) != null) return RubyNumeric.dbl2num(getRuntime(), value);
154
+ if (doesMatch(boolean_pattern, string.toLowerCase())) return RubyBoolean.newBoolean(getRuntime(), Boolean.parseBoolean(string));
143
155
  return RubyString.newString(getRuntime(), string);
144
156
  }
145
157
 
158
+ private Double getDoubleValue(String value) {
159
+ try {
160
+ return Double.valueOf(value);
161
+ } catch (NumberFormatException e) {
162
+ return null;
163
+ }
164
+ }
165
+
146
166
  private boolean doesMatch(Pattern pattern, String string) {
147
167
  Matcher m = pattern.matcher(string);
148
168
  return m.matches();
@@ -166,14 +186,14 @@ public class XmlXpathContext extends RubyObject {
166
186
 
167
187
  @JRubyMethod
168
188
  public IRubyObject register_ns(ThreadContext context, IRubyObject prefix, IRubyObject uri) {
169
- ((NokogiriNamespaceContext) this.xpath.getNamespaceContext()).registerNamespace(prefix.convertToString().asJavaString(), uri.convertToString().asJavaString());
189
+ ((NokogiriNamespaceContext) xpath.getNamespaceContext()).registerNamespace((String)prefix.toJava(String.class), (String)uri.toJava(String.class));
170
190
  return this;
171
191
  }
172
192
 
173
193
  @JRubyMethod
174
194
  public IRubyObject register_variable(ThreadContext context, IRubyObject name, IRubyObject value) {
175
- ((NokogiriXPathVariableResolver) this.xpath.getXPathVariableResolver()).
176
- registerVariable(name.convertToString().asJavaString(), value.convertToString().asJavaString());
195
+ ((NokogiriXPathVariableResolver) xpath.getXPathVariableResolver()).
196
+ registerVariable((String)name.toJava(String.class), (String)value.toJava(String.class));
177
197
  return this;
178
198
  }
179
199
  }
@@ -39,6 +39,7 @@ import java.util.Map;
39
39
  import java.util.regex.Matcher;
40
40
  import java.util.regex.Pattern;
41
41
 
42
+ import javax.xml.transform.ErrorListener;
42
43
  import javax.xml.transform.Templates;
43
44
  import javax.xml.transform.Transformer;
44
45
  import javax.xml.transform.TransformerConfigurationException;
@@ -47,6 +48,8 @@ import javax.xml.transform.TransformerFactory;
47
48
  import javax.xml.transform.dom.DOMResult;
48
49
  import javax.xml.transform.dom.DOMSource;
49
50
 
51
+ import nokogiri.internals.NokogiriXsltErrorListener;
52
+
50
53
  import org.jruby.Ruby;
51
54
  import org.jruby.RubyArray;
52
55
  import org.jruby.RubyClass;
@@ -147,16 +150,27 @@ public class XsltStylesheet extends RubyObject {
147
150
  DOMSource docSource = new DOMSource(((XmlDocument) args[0]).getDocument());
148
151
  DOMResult result = new DOMResult();
149
152
 
153
+ NokogiriXsltErrorListener elistener = new NokogiriXsltErrorListener();
150
154
  try{
151
155
  Transformer transf = this.sheet.newTransformer();
156
+ transf.setErrorListener(elistener);
152
157
  if(args.length > 1) {
153
158
  addParametersToTransformer(context, transf, args[1]);
154
159
  }
155
160
  transf.transform(docSource, result);
156
161
  } catch(TransformerConfigurationException ex) {
157
- throw runtime.newRuntimeError("Could not transform the document.");
162
+ // processes later
158
163
  } catch(TransformerException ex) {
159
- throw runtime.newRuntimeError("Could not transform the document.");
164
+ // processes later
165
+ }
166
+
167
+ switch (elistener.getErrorType()) {
168
+ case ERROR:
169
+ case FATAL:
170
+ throw runtime.newRuntimeError(elistener.getErrorMessage());
171
+ case WARNING:
172
+ default:
173
+ // no-op
160
174
  }
161
175
 
162
176
  if ("html".equals(result.getNode().getFirstChild().getNodeName())) {
@@ -180,4 +194,4 @@ public class XsltStylesheet extends RubyObject {
180
194
  return context.getRuntime().getNil();
181
195
  */
182
196
  }
183
- }
197
+ }