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.

Files changed (137) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +17 -0
  3. data/.travis.yml +6 -6
  4. data/CHANGELOG.ja.rdoc +61 -8
  5. data/CHANGELOG.rdoc +58 -3
  6. data/Gemfile +3 -3
  7. data/Manifest.txt +57 -1
  8. data/README.ja.rdoc +22 -17
  9. data/README.rdoc +23 -18
  10. data/ROADMAP.md +1 -2
  11. data/Rakefile +162 -58
  12. data/build_all +56 -31
  13. data/dependencies.yml +3 -3
  14. data/ext/java/nokogiri/NokogiriService.java +9 -5
  15. data/ext/java/nokogiri/XmlDocument.java +95 -54
  16. data/ext/java/nokogiri/XmlNode.java +93 -42
  17. data/ext/java/nokogiri/XmlReader.java +1 -1
  18. data/ext/java/nokogiri/XmlSaxParserContext.java +33 -0
  19. data/ext/java/nokogiri/XmlSchema.java +4 -2
  20. data/ext/java/nokogiri/XmlXpathContext.java +118 -76
  21. data/ext/java/nokogiri/internals/IgnoreSchemaErrorsErrorHandler.java +20 -0
  22. data/ext/java/nokogiri/internals/NokogiriHandler.java +3 -10
  23. data/ext/java/nokogiri/internals/NokogiriHelpers.java +40 -23
  24. data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +59 -54
  25. data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +1 -1
  26. data/ext/java/nokogiri/internals/ParserContext.java +1 -4
  27. data/ext/java/nokogiri/internals/SaveContextVisitor.java +6 -2
  28. data/ext/java/nokogiri/internals/c14n/AttrCompare.java +119 -0
  29. data/ext/java/nokogiri/internals/c14n/C14nHelper.java +159 -0
  30. data/ext/java/nokogiri/internals/c14n/CanonicalFilter.java +37 -0
  31. data/ext/java/nokogiri/internals/c14n/CanonicalizationException.java +93 -0
  32. data/ext/java/nokogiri/internals/c14n/Canonicalizer.java +252 -0
  33. data/ext/java/nokogiri/internals/c14n/Canonicalizer11.java +639 -0
  34. data/ext/java/nokogiri/internals/c14n/Canonicalizer11_OmitComments.java +38 -0
  35. data/ext/java/nokogiri/internals/c14n/Canonicalizer11_WithComments.java +38 -0
  36. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315.java +368 -0
  37. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315Excl.java +295 -0
  38. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315ExclOmitComments.java +40 -0
  39. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315ExclWithComments.java +44 -0
  40. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315OmitComments.java +44 -0
  41. data/ext/java/nokogiri/internals/c14n/Canonicalizer20010315WithComments.java +43 -0
  42. data/ext/java/nokogiri/internals/c14n/CanonicalizerBase.java +630 -0
  43. data/ext/java/nokogiri/internals/c14n/CanonicalizerPhysical.java +173 -0
  44. data/ext/java/nokogiri/internals/c14n/CanonicalizerSpi.java +76 -0
  45. data/ext/java/nokogiri/internals/c14n/Constants.java +42 -0
  46. data/ext/java/nokogiri/internals/c14n/ElementProxy.java +293 -0
  47. data/ext/java/nokogiri/internals/c14n/HelperNodeList.java +93 -0
  48. data/ext/java/nokogiri/internals/c14n/IgnoreAllErrorHandler.java +79 -0
  49. data/ext/java/nokogiri/internals/c14n/InclusiveNamespaces.java +165 -0
  50. data/ext/java/nokogiri/internals/c14n/InvalidCanonicalizerException.java +76 -0
  51. data/ext/java/nokogiri/internals/c14n/NameSpaceSymbTable.java +402 -0
  52. data/ext/java/nokogiri/internals/c14n/NodeFilter.java +51 -0
  53. data/ext/java/nokogiri/internals/c14n/UtfHelpper.java +179 -0
  54. data/ext/java/nokogiri/internals/c14n/XMLUtils.java +507 -0
  55. data/ext/nokogiri/extconf.rb +429 -128
  56. data/ext/nokogiri/html_document.c +2 -2
  57. data/ext/nokogiri/nokogiri.c +6 -1
  58. data/ext/nokogiri/xml_document.c +5 -4
  59. data/ext/nokogiri/xml_node.c +76 -7
  60. data/ext/nokogiri/xml_reader.c +1 -1
  61. data/ext/nokogiri/xml_sax_parser_context.c +40 -0
  62. data/ext/nokogiri/xml_syntax_error.c +10 -5
  63. data/ext/nokogiri/xml_syntax_error.h +1 -1
  64. data/ext/nokogiri/xml_xpath_context.c +2 -14
  65. data/ext/nokogiri/xslt_stylesheet.c +1 -1
  66. data/lib/nokogiri.rb +31 -22
  67. data/lib/nokogiri/css/node.rb +0 -50
  68. data/lib/nokogiri/css/parser.rb +213 -218
  69. data/lib/nokogiri/css/parser.y +21 -30
  70. data/lib/nokogiri/css/xpath_visitor.rb +62 -14
  71. data/lib/nokogiri/html/document.rb +97 -18
  72. data/lib/nokogiri/html/sax/parser.rb +2 -2
  73. data/lib/nokogiri/nokogiri.jar +0 -0
  74. data/lib/nokogiri/version.rb +1 -1
  75. data/lib/nokogiri/xml/builder.rb +1 -1
  76. data/lib/nokogiri/xml/document.rb +2 -2
  77. data/lib/nokogiri/xml/dtd.rb +10 -0
  78. data/lib/nokogiri/xml/node.rb +26 -1
  79. data/lib/nokogiri/xml/sax/parser.rb +1 -1
  80. data/ports/patches/libxml2/0001-Fix-parser-local-buffers-size-problems.patch +265 -0
  81. data/ports/patches/libxml2/0002-Fix-entities-local-buffers-size-problems.patch +102 -0
  82. data/ports/patches/libxml2/0003-Fix-an-error-in-previous-commit.patch +26 -0
  83. data/ports/patches/libxml2/0004-Fix-potential-out-of-bound-access.patch +26 -0
  84. data/ports/patches/libxml2/0005-Detect-excessive-entities-expansion-upon-replacement.patch +158 -0
  85. data/ports/patches/libxml2/0006-Do-not-fetch-external-parsed-entities.patch +78 -0
  86. data/ports/patches/libxml2/0007-Enforce-XML_PARSER_EOF-state-handling-through-the-pa.patch +480 -0
  87. data/ports/patches/libxml2/0008-Improve-handling-of-xmlStopParser.patch +315 -0
  88. data/ports/patches/libxml2/0009-Fix-a-couple-of-return-without-value.patch +37 -0
  89. data/ports/patches/libxslt/0001-Adding-doc-update-related-to-1.1.28.patch +222 -0
  90. data/ports/patches/libxslt/0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch +53 -0
  91. data/ports/patches/libxslt/0003-Initialize-pseudo-random-number-generator-with-curre.patch +60 -0
  92. data/ports/patches/libxslt/0004-EXSLT-function-str-replace-is-broken-as-is.patch +42 -0
  93. data/ports/patches/libxslt/0006-Fix-str-padding-to-work-with-UTF-8-strings.patch +164 -0
  94. data/ports/patches/libxslt/0007-Separate-function-for-predicate-matching-in-patterns.patch +587 -0
  95. data/ports/patches/libxslt/0008-Fix-direct-pattern-matching.patch +80 -0
  96. data/ports/patches/libxslt/0009-Fix-certain-patterns-with-predicates.patch +185 -0
  97. data/ports/patches/libxslt/0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch +126 -0
  98. data/ports/patches/libxslt/0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch +25 -0
  99. data/ports/patches/libxslt/0014-Fix-for-bug-436589.patch +43 -0
  100. data/ports/patches/libxslt/0015-Fix-mkdir-for-mingw.patch +41 -0
  101. data/suppressions/README.txt +1 -0
  102. data/suppressions/nokogiri_ree-1.8.7.358.supp +61 -0
  103. data/suppressions/nokogiri_ruby-1.8.7.370.supp +0 -0
  104. data/suppressions/nokogiri_ruby-1.9.2.320.supp +28 -0
  105. data/suppressions/nokogiri_ruby-1.9.3.327.supp +28 -0
  106. data/test/css/test_nthiness.rb +65 -2
  107. data/test/css/test_parser.rb +27 -10
  108. data/test/css/test_tokenizer.rb +1 -1
  109. data/test/css/test_xpath_visitor.rb +6 -1
  110. data/test/files/atom.xml +344 -0
  111. data/test/files/shift_jis_no_charset.html +9 -0
  112. data/test/helper.rb +10 -0
  113. data/test/html/test_document.rb +74 -7
  114. data/test/html/test_document_encoding.rb +10 -0
  115. data/test/html/test_document_fragment.rb +9 -3
  116. data/test/namespaces/test_namespaces_aliased_default.rb +24 -0
  117. data/test/namespaces/test_namespaces_in_cloned_doc.rb +31 -0
  118. data/test/namespaces/test_namespaces_preservation.rb +31 -0
  119. data/test/test_nokogiri.rb +6 -0
  120. data/test/test_reader.rb +7 -4
  121. data/test/test_xslt_transforms.rb +25 -0
  122. data/test/xml/sax/test_parser.rb +16 -0
  123. data/test/xml/sax/test_parser_context.rb +9 -0
  124. data/test/xml/test_builder.rb +9 -0
  125. data/test/xml/test_c14n.rb +12 -2
  126. data/test/xml/test_document.rb +66 -0
  127. data/test/xml/test_document_fragment.rb +5 -0
  128. data/test/xml/test_dtd.rb +84 -0
  129. data/test/xml/test_entity_reference.rb +3 -3
  130. data/test/xml/test_node.rb +21 -3
  131. data/test/xml/test_node_attributes.rb +17 -0
  132. data/test/xml/test_schema.rb +26 -0
  133. data/test/xml/test_text.rb +15 -0
  134. data/test/xml/test_xpath.rb +87 -0
  135. data/test_all +3 -3
  136. metadata +119 -68
  137. data/tasks/cross_compile.rb +0 -134
@@ -1,4 +1,4 @@
1
1
  libxml2: "2.8.0"
2
- libxslt: "1.1.26"
3
- zlib: "1.2.7"
4
- libiconv: "1.13.1"
2
+ libxslt: "1.1.28"
3
+ zlib: "1.2.8"
4
+ libiconv: "1.14"
@@ -54,16 +54,18 @@ import org.jruby.runtime.load.BasicLibraryService;
54
54
  */
55
55
  public class NokogiriService implements BasicLibraryService {
56
56
  public static final String nokogiriClassCacheGvarName = "$NOKOGIRI_CLASS_CACHE";
57
- public static Map<String, RubyClass> nokogiriClassCache;
58
57
 
59
58
  public boolean basicLoad(Ruby ruby) {
60
59
  init(ruby);
61
- createNokogiriClassCahce(ruby);
62
60
  return true;
63
61
  }
64
-
65
- private static void createNokogiriClassCahce(Ruby ruby) {
66
- nokogiriClassCache = Collections.synchronizedMap(new HashMap<String, RubyClass>());
62
+
63
+ public static Map<String, RubyClass> getNokogiriClassCache(Ruby ruby) {
64
+ return (Map<String, RubyClass>) ruby.getModule("Nokogiri").getInternalVariable("cache");
65
+ }
66
+
67
+ private static Map<String, RubyClass> populateNokogiriClassCahce(Ruby ruby) {
68
+ Map<String, RubyClass> nokogiriClassCache = Collections.synchronizedMap(new HashMap<String, RubyClass>());
67
69
  nokogiriClassCache.put("Nokogiri::EncodingHandler", (RubyClass)ruby.getClassFromPath("Nokogiri::EncodingHandler"));
68
70
  nokogiriClassCache.put("Nokogiri::HTML::Document", (RubyClass)ruby.getClassFromPath("Nokogiri::HTML::Document"));
69
71
  nokogiriClassCache.put("Nokogiri::HTML::ElementDescription", (RubyClass)ruby.getClassFromPath("Nokogiri::HTML::ElementDescription"));
@@ -91,6 +93,7 @@ public class NokogiriService implements BasicLibraryService {
91
93
  nokogiriClassCache.put("Nokogiri::XML::AttributeDecl", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::AttributeDecl"));
92
94
  nokogiriClassCache.put("Nokogiri::XML::SAX::ParserContext", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::SAX::ParserContext"));
93
95
  nokogiriClassCache.put("StringIO", (RubyClass)ruby.getClassFromPath("StringIO"));
96
+ return nokogiriClassCache;
94
97
  }
95
98
 
96
99
  private void init(Ruby ruby) {
@@ -109,6 +112,7 @@ public class NokogiriService implements BasicLibraryService {
109
112
  createDocuments(ruby, xmlModule, htmlModule, xmlNode);
110
113
  createSaxModule(ruby, xmlSaxModule, htmlSaxModule);
111
114
  createXsltModule(ruby, xsltModule);
115
+ nokogiri.setInternalVariable("cache", populateNokogiriClassCahce(ruby));
112
116
  }
113
117
 
114
118
  private void createJavaLibraryVersionConstants(Ruby ruby, RubyModule nokogiri) {
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * (The MIT License)
3
3
  *
4
- * Copyright (c) 2008 - 2011:
4
+ * Copyright (c) 2008 - 2014:
5
5
  *
6
6
  * * {Aaron Patterson}[http://tenderlovemaking.com]
7
7
  * * {Mike Dalessio}[http://mike.daless.io]
@@ -17,10 +17,10 @@
17
17
  * distribute, sublicense, and/or sell copies of the Software, and to
18
18
  * permit persons to whom the Software is furnished to do so, subject to
19
19
  * the following conditions:
20
- *
20
+ *
21
21
  * The above copyright notice and this permission notice shall be
22
22
  * included in all copies or substantial portions of the Software.
23
- *
23
+ *
24
24
  * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
25
25
  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26
26
  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
@@ -32,12 +32,14 @@
32
32
 
33
33
  package nokogiri;
34
34
 
35
+ import static nokogiri.internals.NokogiriHelpers.clearXpathContext;
35
36
  import static nokogiri.internals.NokogiriHelpers.getCachedNodeOrCreate;
36
37
  import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
37
38
  import static nokogiri.internals.NokogiriHelpers.isNamespace;
38
39
  import static nokogiri.internals.NokogiriHelpers.rubyStringToString;
39
40
  import static nokogiri.internals.NokogiriHelpers.stringOrNil;
40
41
 
42
+ import java.io.UnsupportedEncodingException;
41
43
  import java.util.List;
42
44
 
43
45
  import javax.xml.parsers.DocumentBuilderFactory;
@@ -47,13 +49,15 @@ import nokogiri.internals.NokogiriHelpers;
47
49
  import nokogiri.internals.NokogiriNamespaceCache;
48
50
  import nokogiri.internals.SaveContextVisitor;
49
51
  import nokogiri.internals.XmlDomParserContext;
52
+ import nokogiri.internals.c14n.CanonicalFilter;
53
+ import nokogiri.internals.c14n.CanonicalizationException;
54
+ import nokogiri.internals.c14n.Canonicalizer;
50
55
 
51
56
  import org.jruby.Ruby;
52
57
  import org.jruby.RubyArray;
53
58
  import org.jruby.RubyClass;
54
59
  import org.jruby.RubyFixnum;
55
60
  import org.jruby.RubyNil;
56
- import org.jruby.RubyString;
57
61
  import org.jruby.anno.JRubyClass;
58
62
  import org.jruby.anno.JRubyMethod;
59
63
  import org.jruby.javasupport.JavaUtil;
@@ -74,17 +78,18 @@ import org.w3c.dom.NodeList;
74
78
  *
75
79
  * @author sergio
76
80
  * @author Yoko Harada <yokolet@gmail.com>
81
+ * @author John Shahid <jvshahid@gmail.com>
77
82
  */
78
83
 
79
84
  @JRubyClass(name="Nokogiri::XML::Document", parent="Nokogiri::XML::Node")
80
85
  public class XmlDocument extends XmlNode {
81
86
  private NokogiriNamespaceCache nsCache;
82
-
87
+
83
88
  /* UserData keys for storing extra info in the document node. */
84
89
  public final static String DTD_RAW_DOCUMENT = "DTD_RAW_DOCUMENT";
85
90
  public final static String DTD_INTERNAL_SUBSET = "DTD_INTERNAL_SUBSET";
86
91
  public final static String DTD_EXTERNAL_SUBSET = "DTD_EXTERNAL_SUBSET";
87
-
92
+
88
93
  /* DocumentBuilderFactory implementation class name. This needs to set a classloader into it.
89
94
  * Setting an appropriate classloader resolves issue 380.
90
95
  */
@@ -100,7 +105,7 @@ public class XmlDocument extends XmlNode {
100
105
  public XmlDocument(Ruby ruby, RubyClass klazz) {
101
106
  super(ruby, klazz, createNewDocument());
102
107
  }
103
-
108
+
104
109
  public XmlDocument(Ruby ruby, Document document) {
105
110
  this(ruby, getNokogiriClass(ruby, "Nokogiri::XML::Document"), document);
106
111
  }
@@ -112,7 +117,7 @@ public class XmlDocument extends XmlNode {
112
117
  stabilizeTextContent(document);
113
118
  setInstanceVariable("@decorators", ruby.getNil());
114
119
  }
115
-
120
+
116
121
  public void setDocumentNode(ThreadContext context, Node node) {
117
122
  super.setNode(context, node);
118
123
  initializeNamespaceCacheIfNecessary();
@@ -128,11 +133,11 @@ public class XmlDocument extends XmlNode {
128
133
  public void setEncoding(IRubyObject encoding) {
129
134
  this.encoding = encoding;
130
135
  }
131
-
136
+
132
137
  public IRubyObject getEncoding() {
133
138
  return encoding;
134
139
  }
135
-
140
+
136
141
  // not sure, but like attribute values, text value will be lost
137
142
  // unless it is referred once before this document is used.
138
143
  // this seems to happen only when the fragment is parsed from Node#in_context.
@@ -164,7 +169,7 @@ public class XmlDocument extends XmlNode {
164
169
  createAndCacheNamespaces(ruby, children.item(i));
165
170
  }
166
171
  }
167
-
172
+
168
173
  // When a document is created from fragment with a context (reference) document,
169
174
  // namespace should be resolved based on the context document.
170
175
  public XmlDocument(Ruby ruby, RubyClass klass, Document document, XmlDocument contextDoc) {
@@ -174,14 +179,14 @@ public class XmlDocument extends XmlNode {
174
179
  String default_href = rubyStringToString(default_ns.href(ruby.getCurrentContext()));
175
180
  resolveNamespaceIfNecessary(ruby.getCurrentContext(), document.getDocumentElement(), default_href);
176
181
  }
177
-
182
+
178
183
  private void resolveNamespaceIfNecessary(ThreadContext context, Node node, String default_href) {
179
184
  if (node == null) return;
180
185
  String nodePrefix = node.getPrefix();
181
186
  if (nodePrefix == null) { // default namespace
182
187
  NokogiriHelpers.renameNode(node, default_href, node.getNodeName());
183
188
  } else {
184
- XmlNamespace xmlNamespace = nsCache.get(nodePrefix);
189
+ XmlNamespace xmlNamespace = nsCache.get(node, nodePrefix);
185
190
  String href = rubyStringToString(xmlNamespace.href(context));
186
191
  NokogiriHelpers.renameNode(node, href, node.getNodeName());
187
192
  }
@@ -189,17 +194,17 @@ public class XmlDocument extends XmlNode {
189
194
  NodeList children = node.getChildNodes();
190
195
  for (int i=0; i<children.getLength(); i++) {
191
196
  resolveNamespaceIfNecessary(context, children.item(i), default_href);
192
- }
197
+ }
193
198
  }
194
199
 
195
200
  public NokogiriNamespaceCache getNamespaceCache() {
196
201
  return nsCache;
197
202
  }
198
-
203
+
199
204
  public void initializeNamespaceCacheIfNecessary() {
200
205
  if (nsCache == null) nsCache = new NokogiriNamespaceCache();
201
206
  }
202
-
207
+
203
208
  public void setNamespaceCache(NokogiriNamespaceCache nsCache) {
204
209
  this.nsCache = nsCache;
205
210
  }
@@ -207,7 +212,7 @@ public class XmlDocument extends XmlNode {
207
212
  public Document getDocument() {
208
213
  return (Document) node;
209
214
  }
210
-
215
+
211
216
  @Override
212
217
  protected IRubyObject getNodeName(ThreadContext context) {
213
218
  if (name == null) name = context.getRuntime().newString("document");
@@ -263,7 +268,7 @@ public class XmlDocument extends XmlNode {
263
268
 
264
269
  return xmlDocument;
265
270
  }
266
-
271
+
267
272
  @JRubyMethod(required=1, optional=4)
268
273
  public IRubyObject create_entity(ThreadContext context, IRubyObject[] argv) {
269
274
  // FIXME: Entity node should be create by some right way.
@@ -346,14 +351,15 @@ public class XmlDocument extends XmlNode {
346
351
  getNokogiriClass(context.getRuntime(), "Nokogiri::XML::Document"),
347
352
  args);
348
353
  }
349
-
354
+
350
355
  @JRubyMethod(name="remove_namespaces!")
351
356
  public IRubyObject remove_namespaces(ThreadContext context) {
352
357
  removeNamespceRecursively(context, this);
353
358
  nsCache.clear();
359
+ clearXpathContext(getNode());
354
360
  return this;
355
361
  }
356
-
362
+
357
363
  private void removeNamespceRecursively(ThreadContext context, XmlNode xmlNode) {
358
364
  Node node = xmlNode.node;
359
365
  if (node.getNodeType() == Node.ELEMENT_NODE) {
@@ -395,7 +401,7 @@ public class XmlDocument extends XmlNode {
395
401
  @JRubyMethod(name="root=")
396
402
  public IRubyObject root_set(ThreadContext context, IRubyObject newRoot_) {
397
403
  // in case of document fragment, temporary root node should be deleted.
398
-
404
+
399
405
  // Java can't have a root whose value is null. Instead of setting null,
400
406
  // the method sets user data so that other methods are able to know the root
401
407
  // should be nil.
@@ -444,11 +450,22 @@ public class XmlDocument extends XmlNode {
444
450
  dtd = XmlDtd.newFromInternalSubset(context.getRuntime(), document);
445
451
  } else if (document.getDoctype() != null) {
446
452
  DocumentType docType = document.getDoctype();
453
+ IRubyObject name, publicId, systemId;
454
+ name = publicId = systemId = context.getRuntime().getNil();
455
+ if (docType.getName() != null) {
456
+ name = context.getRuntime().newString(docType.getName());
457
+ }
458
+ if (docType.getPublicId() != null) {
459
+ publicId = context.getRuntime().newString(docType.getPublicId());
460
+ }
461
+ if (docType.getSystemId() != null) {
462
+ systemId = context.getRuntime().newString(docType.getSystemId());
463
+ }
447
464
  dtd = XmlDtd.newEmpty(context.getRuntime(),
448
465
  document,
449
- context.getRuntime().newString(docType.getName()),
450
- context.getRuntime().newString(docType.getPublicId()),
451
- context.getRuntime().newString(docType.getSystemId()));
466
+ name,
467
+ publicId,
468
+ systemId);
452
469
  } else {
453
470
  dtd = context.getRuntime().getNil();
454
471
  }
@@ -531,7 +548,7 @@ public class XmlDocument extends XmlNode {
531
548
  }
532
549
  visitor.leave(document);
533
550
  }
534
-
551
+
535
552
  @JRubyMethod(meta=true)
536
553
  public static IRubyObject wrapJavaDocument(ThreadContext context, IRubyObject klazz, IRubyObject arg) {
537
554
  XmlDocument xmlDocument = (XmlDocument) NokogiriService.XML_DOCUMENT_ALLOCATOR.allocate(context.getRuntime(), getNokogiriClass(context.getRuntime(), "Nokogiri::XML::Document"));
@@ -540,53 +557,77 @@ public class XmlDocument extends XmlNode {
540
557
  xmlDocument.setDocumentNode(context, document);
541
558
  return xmlDocument;
542
559
  }
543
-
560
+
544
561
  @JRubyMethod
545
562
  public IRubyObject toJavaDocument(ThreadContext context) {
546
- return JavaUtil.convertJavaToUsableRubyObject(context.getRuntime(), (org.w3c.dom.Document)node);
563
+ return JavaUtil.convertJavaToUsableRubyObject(context.getRuntime(), node);
547
564
  }
548
-
565
+
549
566
  /* call-seq:
550
567
  * doc.canonicalize(mode=XML_C14N_1_0,inclusive_namespaces=nil,with_comments=false)
551
568
  * doc.canonicalize { |obj, parent| ... }
552
569
  *
553
570
  * Canonicalize a document and return the results. Takes an optional block
554
- * that takes two parameters: the +obj+ and that node's +parent+.
571
+ * that takes two parameters: the +obj+ and that node's +parent+.
555
572
  * The +obj+ will be either a Nokogiri::XML::Node, or a Nokogiri::XML::Namespace
556
- * The block must return a non-nil, non-false value if the +obj+ passed in
573
+ * The block must return a non-nil, non-false value if the +obj+ passed in
557
574
  * should be included in the canonicalized document.
558
575
  */
559
576
  @JRubyMethod(optional=3)
560
577
  public IRubyObject canonicalize(ThreadContext context, IRubyObject[] args, Block block) {
561
- XmlNode startingNode = getStartingNode(block);
562
- int canonicalOpts = 1;
563
- int mode = 0;
564
- if (args.length == 3) {
565
- mode = (Integer)(args[0].isNil() ? 0 : args[0].toJava(Integer.class));
566
- if (mode == 1) canonicalOpts = canonicalOpts | 16; // exclusive
567
- // inclusive prefix list for exclusive c14n
568
- canonicalOpts = args[2].isTrue() ? (canonicalOpts | 4) : canonicalOpts;
578
+ Integer mode = 0;
579
+ String inclusive_namespace = null;
580
+ Boolean with_comments = false;
581
+ if (args.length > 0 && !(args[0].isNil())) {
582
+ mode = RubyFixnum.fix2int(args[0]);
569
583
  }
570
- if (startingNode != this) canonicalOpts = canonicalOpts | 8; // subsets
571
- // 38 = NO_DECL | NO_EMPTY | AS_XML
572
- SaveContextVisitor visitor = new SaveContextVisitor(38, null, "UTF-8", false, false, canonicalOpts);
573
- if (args.length == 3 && !args[1].isNil()) {
574
- visitor.setC14nExclusiveInclusivePrefixes((List<String>)NokogiriHelpers.rubyStringArrayToJavaList((RubyArray)args[1]));
584
+ if (args.length > 1 ) {
585
+ if (!args[1].isNil() && !(args[1] instanceof List)) {
586
+ throw context.getRuntime().newTypeError("Expected array");
587
+ }
588
+ if (!args[1].isNil()) {
589
+ inclusive_namespace = (String)((RubyArray)args[1]).get(0);
590
+ }
575
591
  }
576
- startingNode.accept(context, visitor);
577
- Ruby runtime = context.getRuntime();
578
- IRubyObject result = runtime.getTrue();
579
- if (block.isGiven()) {
580
- List<Node> list = visitor.getC14nNodeList();
581
- for (Node n : list) {
582
- IRubyObject currentNode = getCachedNodeOrCreate(runtime, n);
583
- IRubyObject parentNode = getCachedNodeOrCreate(runtime, n.getParentNode());
584
- result = block.call(context, currentNode, parentNode);
592
+ if (args.length > 2) {
593
+ with_comments = args[2].isTrue();
594
+ }
595
+ String algorithmURI = null;
596
+ switch(mode) {
597
+ case 0: // XML_C14N_1_0
598
+ if (with_comments) algorithmURI = Canonicalizer.ALGO_ID_C14N_WITH_COMMENTS;
599
+ else algorithmURI = Canonicalizer.ALGO_ID_C14N_OMIT_COMMENTS;
600
+ break;
601
+ case 1: // XML_C14N_EXCLUSIVE_1_0
602
+ if (with_comments) algorithmURI = Canonicalizer.ALGO_ID_C14N_EXCL_WITH_COMMENTS;
603
+ else algorithmURI = Canonicalizer.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;
604
+ break;
605
+ case 2: // XML_C14N_1_1 = 2
606
+ if (with_comments) algorithmURI = Canonicalizer.ALGO_ID_C14N11_WITH_COMMENTS;
607
+ else algorithmURI = Canonicalizer.ALGO_ID_C14N11_OMIT_COMMENTS;
608
+ }
609
+ try {
610
+ Canonicalizer canonicalizer = Canonicalizer.getInstance(algorithmURI);
611
+ XmlNode startingNode = getStartingNode(block);
612
+ byte[] result;
613
+ CanonicalFilter filter = new CanonicalFilter(context, block);
614
+ if (inclusive_namespace == null) {
615
+ result = canonicalizer.canonicalizeSubtree(startingNode.getNode(), filter);
616
+ } else {
617
+ result = canonicalizer.canonicalizeSubtree(startingNode.getNode(), inclusive_namespace, filter);
585
618
  }
619
+ String resultString = new String(result, "UTF-8");
620
+ return stringOrNil(context.getRuntime(), resultString);
621
+ } catch (CanonicalizationException e) {
622
+ // TODO Auto-generated catch block
623
+ e.printStackTrace();
624
+ } catch (UnsupportedEncodingException e) {
625
+ // TODO Auto-generated catch block
626
+ e.printStackTrace();
586
627
  }
587
- return result.isTrue() ? stringOrNil(runtime, visitor.toString()) : RubyString.newEmptyString(runtime);
628
+ return context.getRuntime().getNil();
588
629
  }
589
-
630
+
590
631
  private XmlNode getStartingNode(Block block) {
591
632
  if (block.isGiven()) {
592
633
  if (block.getBinding().getSelf() instanceof XmlNode) {
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * (The MIT License)
3
3
  *
4
- * Copyright (c) 2008 - 2012:
4
+ * Copyright (c) 2008 - 2014:
5
5
  *
6
6
  * * {Aaron Patterson}[http://tenderlovemaking.com]
7
7
  * * {Mike Dalessio}[http://mike.daless.io]
@@ -34,6 +34,8 @@ package nokogiri;
34
34
 
35
35
  import static java.lang.Math.max;
36
36
  import static nokogiri.internals.NokogiriHelpers.getCachedNodeOrCreate;
37
+ import static nokogiri.internals.NokogiriHelpers.clearCachedNode;
38
+ import static nokogiri.internals.NokogiriHelpers.clearXpathContext;
37
39
  import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
38
40
  import static nokogiri.internals.NokogiriHelpers.nodeArrayToRubyArray;
39
41
  import static nokogiri.internals.NokogiriHelpers.nonEmptyStringOrNil;
@@ -85,9 +87,11 @@ import org.w3c.dom.Text;
85
87
  * @author sergio
86
88
  * @author Patrick Mahoney <pat@polycrystal.org>
87
89
  * @author Yoko Harada <yokolet@gmail.com>
90
+ * @author John Shahid <jvshahid@gmail.com>
88
91
  */
89
92
  @JRubyClass(name="Nokogiri::XML::Node")
90
93
  public class XmlNode extends RubyObject {
94
+ protected static final String TEXT_WRAPPER_NAME = "nokogiri_text_wrapper";
91
95
 
92
96
  /** The underlying Node object. */
93
97
  protected Node node;
@@ -238,7 +242,7 @@ public class XmlNode extends RubyObject {
238
242
  public Object clone() throws CloneNotSupportedException {
239
243
  return super.clone();
240
244
  }
241
-
245
+
242
246
  protected void resetCache() {
243
247
  node.setUserData(NokogiriHelpers.CACHED_NODE, this, null);
244
248
  }
@@ -396,7 +400,7 @@ public class XmlNode extends RubyObject {
396
400
  }
397
401
 
398
402
  resultLines[i] = curInd.toString() + curLine;
399
-
403
+
400
404
  if(!curLine.endsWith("/>") && !closingTag) {
401
405
  curInd.append(indentString);
402
406
  }
@@ -447,12 +451,12 @@ public class XmlNode extends RubyObject {
447
451
  return value.length() == 0 ? null : value;
448
452
  }
449
453
 
450
-
451
454
  public void post_add_child(ThreadContext context, XmlNode current, XmlNode child) {
452
455
  }
453
456
 
454
457
  public void relink_namespace(ThreadContext context) {
455
458
  if (node instanceof Element) {
459
+ clearCachedNode(node);
456
460
  Element e = (Element) node;
457
461
  String prefix = e.getPrefix();
458
462
  String currentNS = e.getNamespaceURI();
@@ -476,16 +480,22 @@ public class XmlNode extends RubyObject {
476
480
  attrPrefix = NokogiriHelpers.getPrefix(attr.getNodeName());
477
481
  }
478
482
  String nodeName = attr.getNodeName();
479
- if ("xml".equals(prefix)) {
483
+ if ("xml".equals(attrPrefix)) {
480
484
  nsUri = "http://www.w3.org/XML/1998/namespace";
481
485
  } else if ("xmlns".equals(attrPrefix) || nodeName.equals("xmlns")) {
482
486
  nsUri = "http://www.w3.org/2000/xmlns/";
483
487
  } else {
484
488
  nsUri = attr.lookupNamespaceURI(attrPrefix);
485
489
  }
486
- if (!(nsUri == null || "".equals(nsUri))) {
490
+
491
+ if (nsUri == e.getNamespaceURI()) {
492
+ nsUri = null;
493
+ }
494
+
495
+ if (!(nsUri == null || "".equals(nsUri) || "http://www.w3.org/XML/1998/namespace".equals(nsUri))) {
487
496
  XmlNamespace.createFromAttr(context.getRuntime(), attr);
488
497
  }
498
+ clearCachedNode(attr);
489
499
  NokogiriHelpers.renameNode(attr, nsUri, nodeName);
490
500
  }
491
501
  }
@@ -564,7 +574,9 @@ public class XmlNode extends RubyObject {
564
574
  str = NokogiriHelpers.getLocalPart(str);
565
575
  }
566
576
  if (str == null) str = "";
577
+ if (str.startsWith("#")) str = str.substring(1); // eliminates '#'
567
578
  name = NokogiriHelpers.stringOrBlank(context.getRuntime(), str);
579
+
568
580
  return name;
569
581
  }
570
582
 
@@ -577,23 +589,29 @@ public class XmlNode extends RubyObject {
577
589
  public IRubyObject add_namespace_definition(ThreadContext context,
578
590
  IRubyObject prefix,
579
591
  IRubyObject href) {
592
+ String prefixString = rubyStringToString(prefix);
593
+ String hrefString = rubyStringToString(href);
594
+
595
+ NokogiriNamespaceCache nsCache = NokogiriHelpers.getNamespaceCacheFormNode(node);
596
+ XmlNamespace cachedNamespace = nsCache.get(prefixString, hrefString);
597
+ if (cachedNamespace != null) return cachedNamespace;
598
+
580
599
  Node namespaceOwner;
581
600
  if (node.getNodeType() == Node.ELEMENT_NODE) {
582
601
  namespaceOwner = node;
583
602
  Element element = (Element) node;
584
-
603
+ // adds namespace as node's attribute
585
604
  final String uri = "http://www.w3.org/2000/xmlns/";
586
605
  String qName =
587
- prefix.isNil() ? "xmlns" : "xmlns:" + rubyStringToString(prefix);
588
- element.setAttributeNS(uri, qName, rubyStringToString(href));
606
+ prefix.isNil() ? "xmlns" : "xmlns:" + prefixString;
607
+ element.setAttributeNS(uri, qName, hrefString);
589
608
  }
590
609
  else if (node.getNodeType() == Node.ATTRIBUTE_NODE) namespaceOwner = ((Attr)node).getOwnerElement();
591
610
  else namespaceOwner = node.getParentNode();
592
611
  XmlNamespace ns = XmlNamespace.createFromPrefixAndHref(namespaceOwner, prefix, href);
593
612
  if (node != namespaceOwner) {
594
- this.node = NokogiriHelpers.renameNode(node, ns.getHref(), ns.getPrefix() + node.getLocalName());
613
+ this.node = NokogiriHelpers.renameNode(node, ns.getHref(), ns.getPrefix() + ":" + node.getLocalName());
595
614
  }
596
-
597
615
  updateNodeNamespaceIfNecessary(context, ns);
598
616
 
599
617
  return ns;
@@ -665,7 +683,7 @@ public class XmlNode extends RubyObject {
665
683
  xmlNodeSet.setNodeList(node.getChildNodes());
666
684
  return xmlNodeSet;
667
685
  }
668
-
686
+
669
687
  @JRubyMethod
670
688
  public IRubyObject first_element_child(ThreadContext context) {
671
689
  List<Node> elementNodes = new ArrayList<Node>();
@@ -681,7 +699,7 @@ public class XmlNode extends RubyObject {
681
699
  if (elementNodes.size() == 0) return context.getRuntime().getNil();
682
700
  return getCachedNodeOrCreate(context.getRuntime(), elementNodes.get(elementNodes.size()-1));
683
701
  }
684
-
702
+
685
703
  @JRubyMethod(name = {"element_children", "elements"})
686
704
  public IRubyObject element_children(ThreadContext context) {
687
705
  List<Node> elementNodes = new ArrayList<Node>();
@@ -691,7 +709,7 @@ public class XmlNode extends RubyObject {
691
709
  XmlNodeSet xmlNodeSet = XmlNodeSet.newXmlNodeSet(context, array);
692
710
  return xmlNodeSet;
693
711
  }
694
-
712
+
695
713
  private void addElements(Node n, List<Node> nodes, boolean isFirstOnly) {
696
714
  NodeList children = n.getChildNodes();
697
715
  if (children.getLength() == 0) return;
@@ -753,7 +771,7 @@ public class XmlNode extends RubyObject {
753
771
  XmlDomParserContext ctx;
754
772
  InputStream istream;
755
773
  XmlDocument document;
756
-
774
+
757
775
  IRubyObject d = document(context);
758
776
  Ruby runtime = context.getRuntime();
759
777
  if (d != null && d instanceof XmlDocument) {
@@ -761,7 +779,7 @@ public class XmlNode extends RubyObject {
761
779
  } else {
762
780
  return runtime.getNil();
763
781
  }
764
-
782
+
765
783
  if (document instanceof HtmlDocument) {
766
784
  klass = getNokogiriClass(runtime, "Nokogiri::HTML::Document");
767
785
  ctx = new HtmlDomParserContext(runtime, options);
@@ -778,7 +796,7 @@ public class XmlNode extends RubyObject {
778
796
 
779
797
  ctx.setInputSource(istream);
780
798
  XmlDocument doc = ctx.parse(context, klass, runtime.getNil());
781
-
799
+
782
800
  RubyArray documentErrors = getErrorArray(document);
783
801
  RubyArray docErrors = getErrorArray(doc);
784
802
  if (isErrorIncreased(documentErrors, docErrors)) {
@@ -789,7 +807,7 @@ public class XmlNode extends RubyObject {
789
807
  XmlNodeSet xmlNodeSet = XmlNodeSet.newXmlNodeSet(context, RubyArray.newArray(runtime));
790
808
  return xmlNodeSet;
791
809
  }
792
-
810
+
793
811
  // The first child might be document type node (dtd declaration).
794
812
  // XmlNodeSet to be return should not have dtd decl in its list.
795
813
  Node first;
@@ -804,7 +822,7 @@ public class XmlNode extends RubyObject {
804
822
  XmlNodeSet xmlNodeSet = XmlNodeSet.newXmlNodeSet(context, nodeArray);
805
823
  return xmlNodeSet;
806
824
  }
807
-
825
+
808
826
  private RubyArray getErrorArray(XmlDocument document) {
809
827
  IRubyObject obj = document.getInstanceVariable("@errors");
810
828
  if (obj != null && obj instanceof RubyArray) {
@@ -1035,8 +1053,7 @@ public class XmlNode extends RubyObject {
1035
1053
  @JRubyMethod
1036
1054
  public IRubyObject namespace(ThreadContext context) {
1037
1055
  if (doc instanceof HtmlDocument) return context.getRuntime().getNil();
1038
- XmlDocument xmlDocument = (XmlDocument) doc;
1039
- NokogiriNamespaceCache nsCache = xmlDocument.getNamespaceCache();
1056
+ NokogiriNamespaceCache nsCache = NokogiriHelpers.getNamespaceCacheFormNode(node);
1040
1057
  String prefix = node.getPrefix();
1041
1058
  XmlNamespace namespace = nsCache.get(prefix == null ? "" : prefix, node.getNamespaceURI());
1042
1059
  if (namespace == null || namespace.isEmpty()) {
@@ -1074,18 +1091,42 @@ public class XmlNode extends RubyObject {
1074
1091
  */
1075
1092
  @JRubyMethod
1076
1093
  public IRubyObject namespace_scopes(ThreadContext context) {
1077
- RubyArray parentNamespaces;
1078
- RubyArray namespaces = (RubyArray) namespace_definitions(context);
1094
+ RubyArray scoped_namespaces = context.getRuntime().newArray();
1095
+ if (doc == null) return scoped_namespaces;
1096
+ if (doc instanceof HtmlDocument) return scoped_namespaces;
1079
1097
 
1080
- IRubyObject parent = parent(context);
1081
- if (!parent.isNil()) {
1082
- parentNamespaces = (RubyArray)
1083
- ((XmlNode) parent).namespace_scopes(context);
1098
+ Node previousNode;
1099
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
1100
+ previousNode = node;
1101
+ } else if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
1102
+ previousNode = ((Attr)node).getOwnerElement();
1084
1103
  } else {
1085
- parentNamespaces = getRuntime().newEmptyArray();
1104
+ previousNode = findPreviousElement(node);
1105
+ }
1106
+ if (previousNode == null) return scoped_namespaces;
1107
+
1108
+ List<String> prefixes_in_scope = new ArrayList<String>();
1109
+ NokogiriNamespaceCache nsCache = NokogiriHelpers.getNamespaceCacheFormNode(previousNode);
1110
+ for (Node previous=previousNode; previous != null; ) {
1111
+ List<XmlNamespace> namespaces = nsCache.get(previous);
1112
+ for (XmlNamespace namespace : namespaces) {
1113
+ if (prefixes_in_scope.contains(namespace.getPrefix())) continue;
1114
+ scoped_namespaces.append(namespace);
1115
+ prefixes_in_scope.add(namespace.getPrefix());
1116
+ }
1117
+ previous = findPreviousElement(previous);
1086
1118
  }
1119
+ return scoped_namespaces;
1120
+ }
1087
1121
 
1088
- return parentNamespaces.op_plus(namespaces);
1122
+ private Node findPreviousElement(Node n) {
1123
+ Node previous = n.getPreviousSibling() == null ? n.getParentNode() : n.getPreviousSibling();
1124
+ if (previous == null || previous.getNodeType() == Node.DOCUMENT_NODE) return null;
1125
+ if (previous.getNodeType() == Node.ELEMENT_NODE) {
1126
+ return previous;
1127
+ } else {
1128
+ return findPreviousElement(previous);
1129
+ }
1089
1130
  }
1090
1131
 
1091
1132
  @JRubyMethod(name="namespaced_key?")
@@ -1150,11 +1191,11 @@ public class XmlNode extends RubyObject {
1150
1191
 
1151
1192
  return io;
1152
1193
  }
1153
-
1194
+
1154
1195
  private boolean isHtmlDoc(ThreadContext context) {
1155
1196
  return document(context).getMetaClass().isKindOfModule(getNokogiriClass(context.getRuntime(), "Nokogiri::HTML::Document"));
1156
1197
  }
1157
-
1198
+
1158
1199
  private boolean isFragment() {
1159
1200
  if (node instanceof DocumentFragment) return true;
1160
1201
  if (node.getParentNode() != null && node.getParentNode() instanceof DocumentFragment) return true;
@@ -1217,6 +1258,7 @@ public class XmlNode extends RubyObject {
1217
1258
  } else {
1218
1259
  element.setAttribute(key, val);
1219
1260
  }
1261
+ clearXpathContext(node);
1220
1262
  return this;
1221
1263
  } else {
1222
1264
  return rbval;
@@ -1304,6 +1346,8 @@ public class XmlNode extends RubyObject {
1304
1346
  this.node = NokogiriHelpers.renameNode(node, href, new_name);
1305
1347
  }
1306
1348
 
1349
+ clearXpathContext(getNode());
1350
+
1307
1351
  return this;
1308
1352
  }
1309
1353
 
@@ -1312,6 +1356,7 @@ public class XmlNode extends RubyObject {
1312
1356
  if(node.getParentNode() == null) {
1313
1357
  throw context.getRuntime().newRuntimeError("TYPE: " + node.getNodeType()+ " PARENT NULL");
1314
1358
  } else {
1359
+ clearXpathContext(node.getParentNode());
1315
1360
  node.getParentNode().removeChild(node);
1316
1361
  }
1317
1362
 
@@ -1432,6 +1477,8 @@ public class XmlNode extends RubyObject {
1432
1477
  try {
1433
1478
  Document prev = otherNode.getOwnerDocument();
1434
1479
  Document doc = thisNode.getOwnerDocument();
1480
+ clearXpathContext(prev);
1481
+ clearXpathContext(doc);
1435
1482
  if (doc != null && doc != otherNode.getOwnerDocument()) {
1436
1483
  Node ret = doc.adoptNode(otherNode);
1437
1484
  // FIXME: this is really a hack, see documentation of fixUserData() for more details.
@@ -1498,14 +1545,18 @@ public class XmlNode extends RubyObject {
1498
1545
  * text node as the root element. Java (and XML spec?) does
1499
1546
  * not. So we wrap the text node in an element.
1500
1547
  */
1501
- if (parent.getNodeType() == Node.DOCUMENT_NODE &&
1502
- otherNode.getNodeType() == Node.TEXT_NODE) {
1503
- Element e = ((Document)parent).createElement("nokogiri_text_wrapper");
1504
- e.appendChild(otherNode);
1505
- otherNode = e;
1506
- }
1507
- addNamespaceURIIfNeeded(otherNode);
1508
- parent.appendChild(otherNode);
1548
+ if (parent.getNodeType() == Node.DOCUMENT_NODE && otherNode.getNodeType() == Node.TEXT_NODE) {
1549
+ Element e = (Element) parent.getFirstChild();
1550
+ if (e == null || !e.getNodeName().equals(TEXT_WRAPPER_NAME)) {
1551
+ e = ((Document)parent).createElement(TEXT_WRAPPER_NAME);
1552
+ adoptAsChild(context, parent, e);
1553
+ }
1554
+ e.appendChild(otherNode);
1555
+ otherNode = e;
1556
+ } else {
1557
+ addNamespaceURIIfNeeded(otherNode);
1558
+ parent.appendChild(otherNode);
1559
+ }
1509
1560
  Node[] nodes = new Node[1];
1510
1561
  nodes[0] = otherNode;
1511
1562
  return nodes;
@@ -1554,7 +1605,7 @@ public class XmlNode extends RubyObject {
1554
1605
  if (nextSib != null &&
1555
1606
  nextSib.getNodeType() == Node.TEXT_NODE &&
1556
1607
  otherNode.getNodeType() == Node.TEXT_NODE) return;
1557
-
1608
+
1558
1609
  if (nextSib != null) {
1559
1610
  parent.insertBefore(otherNode, nextSib);
1560
1611
  } else {
@@ -1580,7 +1631,7 @@ public class XmlNode extends RubyObject {
1580
1631
  throw context.getRuntime().newRuntimeError(prefix + e.toString());
1581
1632
  }
1582
1633
  }
1583
-
1634
+
1584
1635
  /**
1585
1636
  * Add <code>other</code> as a child of <code>this</code>.
1586
1637
  */
@@ -1612,7 +1663,7 @@ public class XmlNode extends RubyObject {
1612
1663
  public IRubyObject add_next_sibling_node(ThreadContext context, IRubyObject other) {
1613
1664
  return adoptAs(context, AdoptScheme.NEXT_SIBLING, other);
1614
1665
  }
1615
-
1666
+
1616
1667
  /**
1617
1668
  * call-seq:
1618
1669
  * process_xincludes(options)