nokogiri 1.5.6.rc3-java → 1.5.7-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.
- data/CHANGELOG.ja.rdoc +87 -26
- data/CHANGELOG.rdoc +94 -32
- data/Manifest.txt +1 -0
- data/Rakefile +28 -15
- data/build_all +13 -5
- data/ext/java/nokogiri/NokogiriService.java +8 -1
- data/ext/java/nokogiri/XmlDocument.java +4 -4
- data/ext/java/nokogiri/XmlDtd.java +13 -2
- data/ext/java/nokogiri/XmlElement.java +3 -12
- data/ext/java/nokogiri/XmlEntityReference.java +11 -31
- data/ext/java/nokogiri/XmlNode.java +76 -32
- data/ext/java/nokogiri/XmlReader.java +257 -181
- data/ext/java/nokogiri/XmlSaxPushParser.java +17 -2
- data/ext/java/nokogiri/internals/NokogiriHelpers.java +23 -16
- data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +18 -1
- data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler.java +9 -0
- data/ext/java/nokogiri/internals/ReaderNode.java +37 -37
- data/ext/java/nokogiri/internals/SaveContextVisitor.java +23 -16
- data/ext/java/nokogiri/internals/UncloseableInputStream.java +102 -0
- data/ext/java/nokogiri/internals/XmlDomParserContext.java +7 -4
- data/ext/nokogiri/extconf.rb +1 -0
- data/ext/nokogiri/nokogiri.h +4 -0
- data/ext/nokogiri/xml_node.c +33 -1
- data/ext/nokogiri/xml_reader.c +0 -3
- data/ext/nokogiri/xml_sax_parser.c +4 -1
- data/lib/nekodtd.jar +0 -0
- data/lib/nokogiri.rb +1 -0
- data/lib/nokogiri/css/xpath_visitor.rb +1 -1
- data/lib/nokogiri/nokogiri.jar +0 -0
- data/lib/nokogiri/version.rb +4 -1
- data/lib/nokogiri/xml/builder.rb +12 -2
- data/lib/nokogiri/xml/document.rb +3 -1
- data/lib/nokogiri/xml/sax/parser.rb +1 -0
- data/tasks/cross_compile.rb +15 -15
- data/test/css/test_parser.rb +9 -9
- data/test/css/test_xpath_visitor.rb +1 -1
- data/test/helper.rb +1 -0
- data/test/html/sax/test_parser.rb +5 -2
- data/test/html/test_document_fragment.rb +4 -2
- data/test/namespaces/test_namespaces_in_builder_doc.rb +60 -0
- data/test/namespaces/test_namespaces_in_created_doc.rb +62 -0
- data/test/namespaces/test_namespaces_in_parsed_doc.rb +60 -0
- data/test/test_reader.rb +38 -4
- data/test/xml/sax/test_parser.rb +10 -1
- data/test/xml/test_builder.rb +40 -1
- data/test/xml/test_document.rb +50 -2
- data/test/xml/test_entity_reference.rb +2 -4
- data/test/xml/test_node.rb +30 -1
- data/test_all +2 -2
- metadata +142 -232
data/Manifest.txt
CHANGED
@@ -66,6 +66,7 @@ ext/java/nokogiri/internals/ParserContext.java
|
|
66
66
|
ext/java/nokogiri/internals/ReaderNode.java
|
67
67
|
ext/java/nokogiri/internals/SaveContextVisitor.java
|
68
68
|
ext/java/nokogiri/internals/SchemaErrorHandler.java
|
69
|
+
ext/java/nokogiri/internals/UncloseableInputStream.java
|
69
70
|
ext/java/nokogiri/internals/XmlDeclHandler.java
|
70
71
|
ext/java/nokogiri/internals/XmlDomParserContext.java
|
71
72
|
ext/java/nokogiri/internals/XmlSaxParser.java
|
data/Rakefile
CHANGED
@@ -7,7 +7,7 @@ Hoe.plugin :debugging
|
|
7
7
|
Hoe.plugin :git
|
8
8
|
Hoe.plugin :gemspec
|
9
9
|
Hoe.plugin :bundler
|
10
|
-
Hoe.add_include_dirs '.'
|
10
|
+
Hoe.add_include_dirs '.'
|
11
11
|
|
12
12
|
GENERATED_PARSER = "lib/nokogiri/css/parser.rb"
|
13
13
|
GENERATED_TOKENIZER = "lib/nokogiri/css/tokenizer.rb"
|
@@ -35,7 +35,7 @@ HOE = Hoe.spec 'nokogiri' do
|
|
35
35
|
self.clean_globs += [
|
36
36
|
'nokogiri.gemspec',
|
37
37
|
'lib/nokogiri/nokogiri.{bundle,jar,rb,so}',
|
38
|
-
'lib/nokogiri/1.
|
38
|
+
'lib/nokogiri/{1.8,1.9,2.0}',
|
39
39
|
# GENERATED_PARSER,
|
40
40
|
# GENERATED_TOKENIZER
|
41
41
|
]
|
@@ -48,7 +48,7 @@ HOE = Hoe.spec 'nokogiri' do
|
|
48
48
|
["mini_portile", ">= 0.2.2"],
|
49
49
|
["minitest", "~> 2.2.2"],
|
50
50
|
["rake", ">= 0.9"],
|
51
|
-
["rake-compiler", "
|
51
|
+
["rake-compiler", "~> 0.8.0"],
|
52
52
|
["racc", ">= 1.4.6"],
|
53
53
|
["rexical", ">= 1.0.5"]
|
54
54
|
]
|
@@ -67,6 +67,19 @@ end
|
|
67
67
|
|
68
68
|
# ----------------------------------------
|
69
69
|
|
70
|
+
def add_file_to_gem relative_path
|
71
|
+
target_path = File.join gem_build_path, relative_path
|
72
|
+
target_dir = File.dirname(target_path)
|
73
|
+
mkdir_p target_dir unless File.directory?(target_dir)
|
74
|
+
rm_f target_path
|
75
|
+
ln relative_path, target_path
|
76
|
+
HOE.spec.files += [relative_path]
|
77
|
+
end
|
78
|
+
|
79
|
+
def gem_build_path
|
80
|
+
File.join 'pkg', HOE.spec.full_name
|
81
|
+
end
|
82
|
+
|
70
83
|
if java?
|
71
84
|
# TODO: clean this section up.
|
72
85
|
require "rake/javaextensiontask"
|
@@ -78,17 +91,15 @@ if java?
|
|
78
91
|
ext.classpath = jars.map { |x| File.expand_path x }.join ':'
|
79
92
|
end
|
80
93
|
|
81
|
-
gem_build_path = File.join 'pkg', HOE.spec.full_name
|
82
|
-
|
83
94
|
task gem_build_path => [:compile] do
|
84
|
-
|
85
|
-
HOE.spec.files += ['lib/nokogiri/nokogiri.jar']
|
95
|
+
add_file_to_gem 'lib/nokogiri/nokogiri.jar'
|
86
96
|
end
|
87
97
|
else
|
88
98
|
mingw_available = true
|
89
99
|
begin
|
90
100
|
require 'tasks/cross_compile'
|
91
101
|
rescue
|
102
|
+
puts "WARNING: cross compilation not available: #{$!}"
|
92
103
|
mingw_available = false
|
93
104
|
end
|
94
105
|
require "rake/extensiontask"
|
@@ -101,10 +112,10 @@ else
|
|
101
112
|
if mingw_available
|
102
113
|
ext.cross_compile = true
|
103
114
|
ext.cross_platform = ["x86-mswin32-60", "x86-mingw32"]
|
104
|
-
ext.cross_config_options << "--with-xml2-include=#{File.join($recipes[
|
105
|
-
ext.cross_config_options << "--with-xml2-lib=#{File.join($recipes[
|
106
|
-
ext.cross_config_options << "--with-iconv-dir=#{$recipes[
|
107
|
-
ext.cross_config_options << "--with-xslt-dir=#{$recipes[
|
115
|
+
ext.cross_config_options << "--with-xml2-include=#{File.join($recipes["libxml2"].path, 'include', 'libxml2')}"
|
116
|
+
ext.cross_config_options << "--with-xml2-lib=#{File.join($recipes["libxml2"].path, 'lib')}"
|
117
|
+
ext.cross_config_options << "--with-iconv-dir=#{$recipes["libiconv"].path}"
|
118
|
+
ext.cross_config_options << "--with-xslt-dir=#{$recipes["libxslt"].path}"
|
108
119
|
ext.cross_config_options << "--with-zlib-dir=#{CROSS_DIR}"
|
109
120
|
end
|
110
121
|
end
|
@@ -183,8 +194,7 @@ end
|
|
183
194
|
|
184
195
|
desc "build a windows gem without all the ceremony."
|
185
196
|
task "gem:windows" => "gem" do
|
186
|
-
|
187
|
-
cross_rubies = ["1.8.7-p330", "1.9.2-p136"]
|
197
|
+
cross_rubies = ["1.8.7-p358", "1.9.3-p194", "2.0.0-p0"]
|
188
198
|
ruby_cc_version = cross_rubies.collect { |_| _.split("-").first }.join(":") # e.g., "1.8.7:1.9.2"
|
189
199
|
rake_compiler_config_path = "#{ENV['HOME']}/.rake-compiler/config.yml"
|
190
200
|
|
@@ -205,10 +215,13 @@ task "gem:windows" => "gem" do
|
|
205
215
|
end
|
206
216
|
|
207
217
|
# verify that --export-all is in the 1.9 rbconfig. see #279,#374,#375.
|
208
|
-
rbconfig_19 = rake_compiler_config["rbconfig-1.9.
|
218
|
+
rbconfig_19 = rake_compiler_config["rbconfig-1.9.3"]
|
209
219
|
raise "rbconfig #{rbconfig_19} needs --export-all in its DLDFLAGS value" if File.read(rbconfig_19).split("\n").grep(/CONFIG\["DLDFLAGS"\].*--export-all/).empty?
|
210
220
|
|
211
|
-
|
221
|
+
rbconfig_20 = rake_compiler_config["rbconfig-2.0.0"]
|
222
|
+
raise "rbconfig #{rbconfig_20} needs --export-all in its DLDFLAGS value" if File.read(rbconfig_20).split("\n").grep(/CONFIG\["DLDFLAGS"\].*--export-all/).empty?
|
223
|
+
|
224
|
+
pkg_config_path = %w[libxslt libxml2].collect { |pkg| File.join($recipes[pkg].path, "lib/pkgconfig") }.join(":")
|
212
225
|
sh("env PKG_CONFIG_PATH=#{pkg_config_path} RUBY_CC_VERSION=#{ruby_cc_version} rake cross native gem") || raise("build failed!")
|
213
226
|
end
|
214
227
|
|
data/build_all
CHANGED
@@ -31,7 +31,7 @@
|
|
31
31
|
# end
|
32
32
|
#
|
33
33
|
# - you may also have to hack rubygems.rb to eliminate a reference to
|
34
|
-
# RUBY_ENGINE
|
34
|
+
# RUBY_ENGINE (just comment it out)
|
35
35
|
#
|
36
36
|
|
37
37
|
HOST=
|
@@ -71,11 +71,19 @@ if [[ $platform =~ "64" ]] ; then
|
|
71
71
|
exit 1
|
72
72
|
fi
|
73
73
|
rvm_use 1.8.7
|
74
|
-
if [[ ! -a ${HOME}/.rake-compiler/ruby/ruby-1.8.7-
|
75
|
-
|
74
|
+
if [[ ! -a ${HOME}/.rake-compiler/ruby/ruby-1.8.7-p358/lib/ruby/1.8.7/x86_64-linux/rbconfig.rb ]] ; then
|
75
|
+
|
76
|
+
# if this fails around the purelib.rb thing, try varying the ruby
|
77
|
+
# used to run this script, and whether the HOST env var is set
|
78
|
+
# below.
|
79
|
+
|
80
|
+
bundle exec rake-compiler cross-ruby VERSION=1.8.7-p358 # HOST=i386-mingw32
|
81
|
+
fi
|
82
|
+
if [[ ! -a ${HOME}/.rake-compiler/ruby/ruby-1.9.3-p194/lib/ruby/1.9.1/x86_64-linux/rbconfig.rb ]] ; then
|
83
|
+
bundle exec rake-compiler cross-ruby VERSION=1.9.3-p194
|
76
84
|
fi
|
77
|
-
if [[ ! -a ${HOME}/.rake-compiler/ruby/ruby-
|
78
|
-
bundle exec rake-compiler cross-ruby VERSION=
|
85
|
+
if [[ ! -a ${HOME}/.rake-compiler/ruby/ruby-2.0.0-p0/lib/ruby/2.0.0/x86_64-linux/rbconfig.rb ]] ; then
|
86
|
+
bundle exec rake-compiler cross-ruby VERSION=2.0.0-p0
|
79
87
|
fi
|
80
88
|
bundle exec rake cross
|
81
89
|
bundle exec rake gem:windows
|
@@ -90,6 +90,7 @@ public class NokogiriService implements BasicLibraryService {
|
|
90
90
|
nokogiriClassCache.put("Nokogiri::XML::XPathContext", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::XPathContext"));
|
91
91
|
nokogiriClassCache.put("Nokogiri::XML::AttributeDecl", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::AttributeDecl"));
|
92
92
|
nokogiriClassCache.put("Nokogiri::XML::SAX::ParserContext", (RubyClass)ruby.getClassFromPath("Nokogiri::XML::SAX::ParserContext"));
|
93
|
+
nokogiriClassCache.put("StringIO", (RubyClass)ruby.getClassFromPath("StringIO"));
|
93
94
|
}
|
94
95
|
|
95
96
|
private void init(Ruby ruby) {
|
@@ -100,6 +101,7 @@ public class NokogiriService implements BasicLibraryService {
|
|
100
101
|
RubyModule htmlSaxModule = htmlModule.defineModuleUnder("SAX");
|
101
102
|
RubyModule xsltModule = nokogiri.defineModuleUnder("XSLT");
|
102
103
|
|
104
|
+
createJavaLibraryVersionConstants(ruby, nokogiri);
|
103
105
|
createNokogiriModule(ruby, nokogiri);
|
104
106
|
createSyntaxErrors(ruby, nokogiri, xmlModule);
|
105
107
|
RubyClass xmlNode = createXmlModule(ruby, xmlModule);
|
@@ -108,7 +110,12 @@ public class NokogiriService implements BasicLibraryService {
|
|
108
110
|
createSaxModule(ruby, xmlSaxModule, htmlSaxModule);
|
109
111
|
createXsltModule(ruby, xsltModule);
|
110
112
|
}
|
111
|
-
|
113
|
+
|
114
|
+
private void createJavaLibraryVersionConstants(Ruby ruby, RubyModule nokogiri) {
|
115
|
+
nokogiri.defineConstant("XERCES_VERSION", ruby.newString(org.apache.xerces.impl.Version.getVersion()));
|
116
|
+
nokogiri.defineConstant("NEKO_VERSION", ruby.newString(org.cyberneko.html.Version.getVersion()));
|
117
|
+
}
|
118
|
+
|
112
119
|
private void createNokogiriModule(Ruby ruby, RubyModule nokogiri) {;
|
113
120
|
RubyClass encHandler = nokogiri.defineClassUnder("EncodingHandler", ruby.getObject(), ENCODING_HANDLER_ALLOCATOR);
|
114
121
|
encHandler.defineAnnotatedMethods(EncodingHandler.class);
|
@@ -179,11 +179,11 @@ public class XmlDocument extends XmlNode {
|
|
179
179
|
if (node == null) return;
|
180
180
|
String nodePrefix = node.getPrefix();
|
181
181
|
if (nodePrefix == null) { // default namespace
|
182
|
-
|
182
|
+
NokogiriHelpers.renameNode(node, default_href, node.getNodeName());
|
183
183
|
} else {
|
184
184
|
XmlNamespace xmlNamespace = nsCache.get(nodePrefix);
|
185
185
|
String href = rubyStringToString(xmlNamespace.href(context));
|
186
|
-
|
186
|
+
NokogiriHelpers.renameNode(node, href, node.getNodeName());
|
187
187
|
}
|
188
188
|
resolveNamespaceIfNecessary(context, node.getNextSibling(), default_href);
|
189
189
|
NodeList children = node.getChildNodes();
|
@@ -358,7 +358,7 @@ public class XmlDocument extends XmlNode {
|
|
358
358
|
Node node = xmlNode.node;
|
359
359
|
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
360
360
|
node.setPrefix(null);
|
361
|
-
|
361
|
+
NokogiriHelpers.renameNode(node, null, node.getLocalName());
|
362
362
|
NamedNodeMap attrs = node.getAttributes();
|
363
363
|
for (int i=0; i<attrs.getLength(); i++) {
|
364
364
|
Attr attr = (Attr) attrs.item(i);
|
@@ -366,7 +366,7 @@ public class XmlDocument extends XmlNode {
|
|
366
366
|
((org.w3c.dom.Element)node).removeAttributeNode(attr);
|
367
367
|
} else {
|
368
368
|
attr.setPrefix(null);
|
369
|
-
|
369
|
+
NokogiriHelpers.renameNode(attr, null, attr.getLocalName());
|
370
370
|
}
|
371
371
|
}
|
372
372
|
}
|
@@ -129,9 +129,20 @@ public class XmlDtd extends XmlNode {
|
|
129
129
|
IRubyObject name,
|
130
130
|
IRubyObject external_id,
|
131
131
|
IRubyObject system_id) {
|
132
|
-
|
132
|
+
|
133
|
+
DocumentType placeholder = null;
|
134
|
+
if (doc.getDoctype() == null) {
|
135
|
+
String javaName = NokogiriHelpers.rubyStringToString(name);
|
136
|
+
String javaExternalId = NokogiriHelpers.rubyStringToString(external_id);
|
137
|
+
String javaSystemId = NokogiriHelpers.rubyStringToString(system_id);
|
138
|
+
placeholder = doc.getImplementation().createDocumentType(javaName, javaExternalId, javaSystemId);
|
139
|
+
doc.appendChild(placeholder);
|
140
|
+
} else {
|
141
|
+
placeholder = doc.getDoctype();
|
142
|
+
}
|
143
|
+
// FIXME: what if the document had a doc type, why are we here ?
|
133
144
|
XmlDtd dtd = (XmlDtd) NokogiriService.XML_DTD_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::DTD"));
|
134
|
-
dtd.setNode(runtime,
|
145
|
+
dtd.setNode(runtime, placeholder);
|
135
146
|
dtd.name = name;
|
136
147
|
dtd.pubId = external_id;
|
137
148
|
dtd.sysId = system_id;
|
@@ -38,7 +38,6 @@ import org.jruby.Ruby;
|
|
38
38
|
import org.jruby.RubyArray;
|
39
39
|
import org.jruby.RubyClass;
|
40
40
|
import org.jruby.anno.JRubyClass;
|
41
|
-
import org.jruby.javasupport.util.RuntimeHelpers;
|
42
41
|
import org.jruby.runtime.ThreadContext;
|
43
42
|
import org.w3c.dom.Element;
|
44
43
|
import org.w3c.dom.Node;
|
@@ -62,17 +61,9 @@ public class XmlElement extends XmlNode {
|
|
62
61
|
|
63
62
|
@Override
|
64
63
|
public void setNode(ThreadContext context, Node node) {
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
if (node.getNodeType() != Node.DOCUMENT_NODE) {
|
69
|
-
doc = document(context);
|
70
|
-
setInstanceVariable("@document", doc);
|
71
|
-
if (doc != null) {
|
72
|
-
RuntimeHelpers.invoke(context, doc, "decorate", this);
|
73
|
-
}
|
74
|
-
}
|
75
|
-
}
|
64
|
+
super.setNode(context, node);
|
65
|
+
if (doc != null)
|
66
|
+
setInstanceVariable("@document", doc);
|
76
67
|
}
|
77
68
|
|
78
69
|
@Override
|
@@ -36,6 +36,7 @@ import static nokogiri.internals.NokogiriHelpers.getCachedNodeOrCreate;
|
|
36
36
|
import static nokogiri.internals.NokogiriHelpers.rubyStringToString;
|
37
37
|
import nokogiri.internals.SaveContextVisitor;
|
38
38
|
|
39
|
+
import org.apache.xerces.dom.CoreDocumentImpl;
|
39
40
|
import org.jruby.Ruby;
|
40
41
|
import org.jruby.RubyClass;
|
41
42
|
import org.jruby.anno.JRubyClass;
|
@@ -70,21 +71,19 @@ public class XmlEntityReference extends XmlNode {
|
|
70
71
|
IRubyObject doc = args[0];
|
71
72
|
IRubyObject name = args[1];
|
72
73
|
|
73
|
-
Document
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
Node node = new NokogiriEntityReference(owner, name);
|
82
|
-
super.setNode(context, node);
|
74
|
+
Document document = ((XmlNode) doc).getOwnerDocument();
|
75
|
+
// FIXME: disable error checking as a workaround for #719. this depends on the internals of Xerces.
|
76
|
+
CoreDocumentImpl internalDocument = (CoreDocumentImpl) document;
|
77
|
+
boolean oldErrorChecking = internalDocument.getErrorChecking();
|
78
|
+
internalDocument.setErrorChecking(false);
|
79
|
+
Node node = document.createEntityReference(rubyStringToString(name));
|
80
|
+
internalDocument.setErrorChecking(oldErrorChecking);
|
81
|
+
setNode(context, node);
|
83
82
|
}
|
84
83
|
|
85
84
|
@Override
|
86
85
|
public void accept(ThreadContext context, SaveContextVisitor visitor) {
|
87
|
-
visitor.
|
86
|
+
visitor.enter(node);
|
88
87
|
Node child = node.getFirstChild();
|
89
88
|
while (child != null) {
|
90
89
|
IRubyObject nokoNode = getCachedNodeOrCreate(context.getRuntime(), child);
|
@@ -97,25 +96,6 @@ public class XmlEntityReference extends XmlNode {
|
|
97
96
|
}
|
98
97
|
child = child.getNextSibling();
|
99
98
|
}
|
100
|
-
visitor.
|
101
|
-
}
|
102
|
-
|
103
|
-
public class NokogiriEntityReference extends org.apache.xerces.dom.TextImpl {
|
104
|
-
// Nokogiri's EntityReference should quack like a org.w3c.dom.Text node.
|
105
|
-
// EntityReference node should not raise exception for names such as #xa.
|
106
|
-
// This is reported bug in issue#719.
|
107
|
-
// Also, EntityReference node should not bother xpath.
|
108
|
-
// For this purpose, Node type should be Node.TEXT_NODE.
|
109
|
-
public NokogiriEntityReference(Document owner, String name) {
|
110
|
-
super((org.apache.xerces.dom.DocumentImpl)owner, name);
|
111
|
-
}
|
112
|
-
|
113
|
-
public short getNodeType() {
|
114
|
-
return Node.TEXT_NODE;
|
115
|
-
}
|
116
|
-
|
117
|
-
public String getNodeName() {
|
118
|
-
return getNodeValue();
|
119
|
-
}
|
99
|
+
visitor.leave(node);
|
120
100
|
}
|
121
101
|
}
|
@@ -54,6 +54,7 @@ import nokogiri.internals.NokogiriNamespaceCache;
|
|
54
54
|
import nokogiri.internals.SaveContextVisitor;
|
55
55
|
import nokogiri.internals.XmlDomParserContext;
|
56
56
|
|
57
|
+
import org.apache.xerces.dom.CoreDocumentImpl;
|
57
58
|
import org.jruby.Ruby;
|
58
59
|
import org.jruby.RubyArray;
|
59
60
|
import org.jruby.RubyClass;
|
@@ -211,22 +212,23 @@ public class XmlNode extends RubyObject {
|
|
211
212
|
*/
|
212
213
|
public XmlNode(Ruby ruby, RubyClass cls, Node node) {
|
213
214
|
super(ruby, cls);
|
214
|
-
|
215
|
+
setNode(ruby.getCurrentContext(), node);
|
216
|
+
}
|
215
217
|
|
218
|
+
protected void decorate(Ruby ruby) {
|
216
219
|
if (node != null) {
|
217
220
|
resetCache();
|
218
221
|
|
219
222
|
if (node.getNodeType() != Node.DOCUMENT_NODE) {
|
220
223
|
doc = document(ruby.getCurrentContext());
|
221
224
|
|
222
|
-
if (doc != null) {
|
225
|
+
if (doc != null && doc.isTrue()) {
|
223
226
|
RuntimeHelpers.invoke(ruby.getCurrentContext(), doc, "decorate", this);
|
224
227
|
}
|
225
228
|
}
|
226
229
|
}
|
227
|
-
|
228
230
|
}
|
229
|
-
|
231
|
+
|
230
232
|
/**
|
231
233
|
* Create and return a copy of this object.
|
232
234
|
*
|
@@ -326,12 +328,15 @@ public class XmlNode extends RubyObject {
|
|
326
328
|
|
327
329
|
Element element = null;
|
328
330
|
String node_name = rubyStringToString(name);
|
329
|
-
|
330
|
-
|
331
|
-
} catch (org.w3c.dom.DOMException e) {
|
332
|
-
// issue#683 NAMESPACE_ERR is thrown from RDF::RDFXML::Writer.new
|
333
|
-
// retry without namespace
|
331
|
+
String prefix = NokogiriHelpers.getPrefix(node_name);
|
332
|
+
if (prefix == null) {
|
334
333
|
element = document.createElement(node_name);
|
334
|
+
} else {
|
335
|
+
String namespace_uri = null;
|
336
|
+
if (document.getDocumentElement() != null) {
|
337
|
+
namespace_uri = document.getDocumentElement().lookupNamespaceURI(prefix);
|
338
|
+
}
|
339
|
+
element = document.createElementNS(namespace_uri, node_name);
|
335
340
|
}
|
336
341
|
setNode(context, element);
|
337
342
|
}
|
@@ -449,8 +454,16 @@ public class XmlNode extends RubyObject {
|
|
449
454
|
public void relink_namespace(ThreadContext context) {
|
450
455
|
if (node instanceof Element) {
|
451
456
|
Element e = (Element) node;
|
457
|
+
String prefix = e.getPrefix();
|
458
|
+
String currentNS = e.getNamespaceURI();
|
459
|
+
if (prefix == null && currentNS == null) {
|
460
|
+
prefix = NokogiriHelpers.getPrefix(e.getNodeName());
|
461
|
+
} else if (currentNS != null) {
|
462
|
+
prefix = e.lookupPrefix(currentNS);
|
463
|
+
}
|
452
464
|
e.getOwnerDocument().setStrictErrorChecking(false);
|
453
|
-
|
465
|
+
String nsURI = e.lookupNamespaceURI(prefix);
|
466
|
+
this.node = NokogiriHelpers.renameNode(e, nsURI, e.getNodeName());
|
454
467
|
|
455
468
|
if (e.hasAttributes()) {
|
456
469
|
NamedNodeMap attrs = e.getAttributes();
|
@@ -458,24 +471,28 @@ public class XmlNode extends RubyObject {
|
|
458
471
|
for (int i = 0; i < attrs.getLength(); i++) {
|
459
472
|
Attr attr = (Attr) attrs.item(i);
|
460
473
|
String nsUri = "";
|
461
|
-
String
|
474
|
+
String attrPrefix = attr.getPrefix();
|
475
|
+
if (attrPrefix == null) {
|
476
|
+
attrPrefix = NokogiriHelpers.getPrefix(attr.getNodeName());
|
477
|
+
}
|
462
478
|
String nodeName = attr.getNodeName();
|
463
479
|
if ("xml".equals(prefix)) {
|
464
480
|
nsUri = "http://www.w3.org/XML/1998/namespace";
|
465
|
-
} else if ("xmlns".equals(
|
481
|
+
} else if ("xmlns".equals(attrPrefix) || nodeName.equals("xmlns")) {
|
466
482
|
nsUri = "http://www.w3.org/2000/xmlns/";
|
467
483
|
} else {
|
468
|
-
nsUri = attr.
|
484
|
+
nsUri = attr.lookupNamespaceURI(attrPrefix);
|
469
485
|
}
|
470
486
|
if (!(nsUri == null || "".equals(nsUri))) {
|
471
487
|
XmlNamespace.createFromAttr(context.getRuntime(), attr);
|
472
488
|
}
|
473
|
-
|
489
|
+
NokogiriHelpers.renameNode(attr, nsUri, nodeName);
|
474
490
|
}
|
475
491
|
}
|
476
492
|
|
477
|
-
if (
|
478
|
-
(
|
493
|
+
if (this.node.hasChildNodes()) {
|
494
|
+
XmlNodeSet nodeSet = (XmlNodeSet)(children(context));
|
495
|
+
nodeSet.relink_namespace(context);
|
479
496
|
}
|
480
497
|
}
|
481
498
|
}
|
@@ -514,13 +531,8 @@ public class XmlNode extends RubyObject {
|
|
514
531
|
|
515
532
|
public void setNode(ThreadContext context, Node node) {
|
516
533
|
this.node = node;
|
517
|
-
|
518
|
-
|
519
|
-
resetCache();
|
520
|
-
if (node.getNodeType() != Node.DOCUMENT_NODE) {
|
521
|
-
doc = document(context);
|
522
|
-
}
|
523
|
-
}
|
534
|
+
|
535
|
+
decorate(context.getRuntime());
|
524
536
|
|
525
537
|
if (this instanceof XmlAttr) {
|
526
538
|
((XmlAttr)this).setNamespaceIfNecessary(context.getRuntime());
|
@@ -539,7 +551,7 @@ public class XmlNode extends RubyObject {
|
|
539
551
|
&& oldPrefix.equals(rubyStringToString(ns.prefix(context))));
|
540
552
|
|
541
553
|
if(update) {
|
542
|
-
this.node.
|
554
|
+
this.node = NokogiriHelpers.renameNode(this.node, uri, this.node.getNodeName());
|
543
555
|
}
|
544
556
|
}
|
545
557
|
|
@@ -579,7 +591,7 @@ public class XmlNode extends RubyObject {
|
|
579
591
|
else namespaceOwner = node.getParentNode();
|
580
592
|
XmlNamespace ns = XmlNamespace.createFromPrefixAndHref(namespaceOwner, prefix, href);
|
581
593
|
if (node != namespaceOwner) {
|
582
|
-
node.
|
594
|
+
this.node = NokogiriHelpers.renameNode(node, ns.getHref(), ns.getPrefix() + node.getLocalName());
|
583
595
|
}
|
584
596
|
|
585
597
|
updateNodeNamespaceIfNecessary(context, ns);
|
@@ -915,8 +927,9 @@ public class XmlNode extends RubyObject {
|
|
915
927
|
if (rbkey == null || rbkey.isNil()) context.getRuntime().getNil();
|
916
928
|
String key = rubyStringToString(rbkey);
|
917
929
|
Element element = (Element) node;
|
930
|
+
if (!element.hasAttribute(key)) return context.getRuntime().getNil();
|
918
931
|
String value = element.getAttribute(key);
|
919
|
-
return
|
932
|
+
return stringOrNil(context.getRuntime(), value);
|
920
933
|
}
|
921
934
|
return context.getRuntime().getNil();
|
922
935
|
}
|
@@ -1174,7 +1187,7 @@ public class XmlNode extends RubyObject {
|
|
1174
1187
|
@JRubyMethod(name = {"node_name=", "name="})
|
1175
1188
|
public IRubyObject node_name_set(ThreadContext context, IRubyObject nodeName) {
|
1176
1189
|
String newName = rubyStringToString(nodeName);
|
1177
|
-
|
1190
|
+
this.node = NokogiriHelpers.renameNode(node, null, newName);
|
1178
1191
|
setName(nodeName);
|
1179
1192
|
return this;
|
1180
1193
|
}
|
@@ -1192,6 +1205,8 @@ public class XmlNode extends RubyObject {
|
|
1192
1205
|
String uri = null;
|
1193
1206
|
if (prefix.equals("xml")) {
|
1194
1207
|
uri = "http://www.w3.org/XML/1998/namespace";
|
1208
|
+
} else if (prefix.equals("xmlns")) {
|
1209
|
+
uri = "http://www.w3.org/2000/xmlns/";
|
1195
1210
|
} else {
|
1196
1211
|
uri = findNamespaceHref(context, prefix);
|
1197
1212
|
}
|
@@ -1216,7 +1231,11 @@ public class XmlNode extends RubyObject {
|
|
1216
1231
|
return namespace.getHref();
|
1217
1232
|
}
|
1218
1233
|
}
|
1219
|
-
|
1234
|
+
if (currentNode.parent(context).isNil()) {
|
1235
|
+
break;
|
1236
|
+
} else {
|
1237
|
+
currentNode = (XmlNode) currentNode.parent(context);
|
1238
|
+
}
|
1220
1239
|
}
|
1221
1240
|
return null;
|
1222
1241
|
}
|
@@ -1263,7 +1282,7 @@ public class XmlNode extends RubyObject {
|
|
1263
1282
|
String prefix = n.getPrefix();
|
1264
1283
|
String href = n.getNamespaceURI();
|
1265
1284
|
((XmlDocument)doc).getNamespaceCache().remove(prefix == null ? "" : prefix, href);
|
1266
|
-
|
1285
|
+
this.node = NokogiriHelpers.renameNode(n, null, NokogiriHelpers.getLocalPart(n.getNodeName()));
|
1267
1286
|
}
|
1268
1287
|
} else {
|
1269
1288
|
XmlNamespace ns = (XmlNamespace) namespace;
|
@@ -1272,7 +1291,14 @@ public class XmlNode extends RubyObject {
|
|
1272
1291
|
|
1273
1292
|
// Assigning node = ...renameNode() or not seems to make no
|
1274
1293
|
// difference. Why not? -pmahoney
|
1275
|
-
|
1294
|
+
|
1295
|
+
// It actually makes a great deal of difference. renameNode()
|
1296
|
+
// will operate in place if it can, but sometimes it can't.
|
1297
|
+
// The node you passed in *might* come back as you expect, but
|
1298
|
+
// it might not. It's much safer to throw away the original
|
1299
|
+
// and keep the return value. -mbklein
|
1300
|
+
String new_name = NokogiriHelpers.newQName(prefix, node);
|
1301
|
+
this.node = NokogiriHelpers.renameNode(node, href, new_name);
|
1276
1302
|
}
|
1277
1303
|
|
1278
1304
|
return this;
|
@@ -1401,12 +1427,16 @@ public class XmlNode extends RubyObject {
|
|
1401
1427
|
Node otherNode = other.node;
|
1402
1428
|
|
1403
1429
|
try {
|
1430
|
+
Document prev = otherNode.getOwnerDocument();
|
1404
1431
|
Document doc = thisNode.getOwnerDocument();
|
1405
1432
|
if (doc != null && doc != otherNode.getOwnerDocument()) {
|
1406
1433
|
Node ret = doc.adoptNode(otherNode);
|
1434
|
+
// FIXME: this is really a hack, see documentation of fixUserData() for more details.
|
1435
|
+
fixUserData(prev, ret);
|
1407
1436
|
if (ret == null) {
|
1408
1437
|
throw context.getRuntime().newRuntimeError("Failed to take ownership of node");
|
1409
1438
|
}
|
1439
|
+
otherNode = ret;
|
1410
1440
|
}
|
1411
1441
|
|
1412
1442
|
Node parent = thisNode.getParentNode();
|
@@ -1444,6 +1474,20 @@ public class XmlNode extends RubyObject {
|
|
1444
1474
|
return nodeOrTags;
|
1445
1475
|
}
|
1446
1476
|
|
1477
|
+
/**
|
1478
|
+
* This is a hack to fix #839. We should submit a patch to Xerces.
|
1479
|
+
* It looks like CoreDocumentImpl.adoptNode() doesn't copy
|
1480
|
+
* the user data associated with child nodes (recursively).
|
1481
|
+
*/
|
1482
|
+
private void fixUserData(Document previous, Node ret) {
|
1483
|
+
String key = NokogiriHelpers.ENCODED_STRING;
|
1484
|
+
for (Node child = ret.getFirstChild(); child != null; child = child.getNextSibling()) {
|
1485
|
+
CoreDocumentImpl previousDocument = (CoreDocumentImpl) previous;
|
1486
|
+
child.setUserData(key, previousDocument.getUserData(child, key), null);
|
1487
|
+
fixUserData(previous, child);
|
1488
|
+
}
|
1489
|
+
}
|
1490
|
+
|
1447
1491
|
protected Node[] adoptAsChild(ThreadContext context, Node parent,
|
1448
1492
|
Node otherNode) {
|
1449
1493
|
/*
|
@@ -1469,7 +1513,7 @@ public class XmlNode extends RubyObject {
|
|
1469
1513
|
XmlElement fragmentContext = ((XmlDocumentFragment)this).getFragmentContext();
|
1470
1514
|
String namespace_uri = fragmentContext.node.getNamespaceURI();
|
1471
1515
|
if (namespace_uri != null && namespace_uri.length() > 0) {
|
1472
|
-
|
1516
|
+
NokogiriHelpers.renameNode(child, namespace_uri, child.getNodeName());
|
1473
1517
|
}
|
1474
1518
|
}
|
1475
1519
|
}
|
@@ -1526,7 +1570,7 @@ public class XmlNode extends RubyObject {
|
|
1526
1570
|
try {
|
1527
1571
|
parentNode.replaceChild(otherNode, thisNode);
|
1528
1572
|
if (otherNode.getNodeType() != Node.TEXT_NODE) {
|
1529
|
-
|
1573
|
+
NokogiriHelpers.renameNode(otherNode, thisNode.getNamespaceURI(), otherNode.getNodeName());
|
1530
1574
|
}
|
1531
1575
|
} catch (Exception e) {
|
1532
1576
|
String prefix = "could not replace child: ";
|