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
data/dependencies.yml
CHANGED
@@ -1,4 +1,4 @@
|
|
1
1
|
libxml2: "2.8.0"
|
2
|
-
libxslt: "1.1.
|
3
|
-
zlib: "1.2.
|
4
|
-
libiconv: "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
|
-
|
66
|
-
|
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 -
|
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
|
-
|
450
|
-
|
451
|
-
|
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(),
|
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
|
-
|
562
|
-
|
563
|
-
|
564
|
-
if (args.length
|
565
|
-
mode =
|
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 (
|
571
|
-
|
572
|
-
|
573
|
-
|
574
|
-
|
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
|
-
|
577
|
-
|
578
|
-
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
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
|
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 -
|
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(
|
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
|
-
|
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:" +
|
588
|
-
element.setAttributeNS(uri, qName,
|
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
|
-
|
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
|
1078
|
-
|
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
|
-
|
1081
|
-
if (
|
1082
|
-
|
1083
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
1503
|
-
|
1504
|
-
e.
|
1505
|
-
|
1506
|
-
|
1507
|
-
|
1508
|
-
|
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)
|