nokogiri 1.5.0.beta.4 → 1.5.0
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/.gemtest +0 -0
- data/CHANGELOG.ja.rdoc +34 -0
- data/CHANGELOG.rdoc +40 -1
- data/Manifest.txt +11 -2
- data/README.rdoc +1 -1
- data/Rakefile +100 -104
- data/bin/nokogiri +1 -2
- data/ext/nokogiri/nokogiri.c +24 -1
- data/ext/nokogiri/xml_io.c +32 -7
- data/ext/nokogiri/xml_node.c +14 -13
- data/ext/nokogiri/xml_sax_parser.c +9 -4
- data/ext/nokogiri/xslt_stylesheet.c +7 -1
- data/lib/nokogiri.rb +3 -22
- data/lib/nokogiri/css.rb +4 -0
- data/lib/nokogiri/html/document.rb +10 -14
- data/lib/nokogiri/version.rb +76 -23
- data/lib/nokogiri/xml/builder.rb +7 -0
- data/lib/nokogiri/xml/document.rb +17 -1
- data/lib/nokogiri/xml/document_fragment.rb +14 -0
- data/lib/nokogiri/xml/node.rb +36 -28
- data/lib/nokogiri/xml/node/save_options.rb +17 -1
- data/lib/nokogiri/xml/node_set.rb +7 -0
- data/lib/nokogiri/xml/parse_options.rb +8 -0
- data/lib/nokogiri/xml/reader.rb +6 -6
- data/lib/nokogiri/xml/schema.rb +7 -1
- data/nokogiri_help_responses.md +40 -0
- data/tasks/cross_compile.rb +134 -159
- data/tasks/nokogiri.org.rb +18 -0
- data/tasks/test.rb +1 -1
- data/test/files/encoding.html +82 -0
- data/test/files/encoding.xhtml +84 -0
- data/test/files/metacharset.html +10 -0
- data/test/files/noencoding.html +47 -0
- data/test/helper.rb +2 -0
- data/test/html/test_document.rb +15 -0
- data/test/html/test_document_encoding.rb +13 -0
- data/test/test_memory_leak.rb +20 -0
- data/test/test_reader.rb +22 -0
- data/test/test_xslt_transforms.rb +6 -2
- data/test/xml/node/test_save_options.rb +10 -2
- data/test/xml/test_builder.rb +17 -0
- data/test/xml/test_document.rb +22 -0
- data/test/xml/test_node.rb +19 -1
- data/test/xml/test_node_reparenting.rb +16 -3
- data/test/xml/test_node_set.rb +34 -0
- data/test/xml/test_schema.rb +5 -0
- data/test/xslt/test_exception_handling.rb +37 -0
- metadata +185 -157
- data/deps.rip +0 -5
- data/ext/java/nokogiri/EncodingHandler.java +0 -124
- data/ext/java/nokogiri/HtmlDocument.java +0 -149
- data/ext/java/nokogiri/HtmlElementDescription.java +0 -145
- data/ext/java/nokogiri/HtmlEntityLookup.java +0 -79
- data/ext/java/nokogiri/HtmlSaxParserContext.java +0 -259
- data/ext/java/nokogiri/NokogiriService.java +0 -535
- data/ext/java/nokogiri/XmlAttr.java +0 -191
- data/ext/java/nokogiri/XmlAttributeDecl.java +0 -130
- data/ext/java/nokogiri/XmlCdata.java +0 -91
- data/ext/java/nokogiri/XmlComment.java +0 -86
- data/ext/java/nokogiri/XmlDocument.java +0 -529
- data/ext/java/nokogiri/XmlDocumentFragment.java +0 -217
- data/ext/java/nokogiri/XmlDtd.java +0 -467
- data/ext/java/nokogiri/XmlElement.java +0 -222
- data/ext/java/nokogiri/XmlElementContent.java +0 -382
- data/ext/java/nokogiri/XmlElementDecl.java +0 -148
- data/ext/java/nokogiri/XmlEntityDecl.java +0 -162
- data/ext/java/nokogiri/XmlEntityReference.java +0 -75
- data/ext/java/nokogiri/XmlNamespace.java +0 -128
- data/ext/java/nokogiri/XmlNode.java +0 -1399
- data/ext/java/nokogiri/XmlNodeSet.java +0 -311
- data/ext/java/nokogiri/XmlProcessingInstruction.java +0 -103
- data/ext/java/nokogiri/XmlReader.java +0 -411
- data/ext/java/nokogiri/XmlRelaxng.java +0 -144
- data/ext/java/nokogiri/XmlSaxParserContext.java +0 -367
- data/ext/java/nokogiri/XmlSaxPushParser.java +0 -184
- data/ext/java/nokogiri/XmlSchema.java +0 -319
- data/ext/java/nokogiri/XmlSyntaxError.java +0 -119
- data/ext/java/nokogiri/XmlText.java +0 -136
- data/ext/java/nokogiri/XmlXpathContext.java +0 -179
- data/ext/java/nokogiri/XsltStylesheet.java +0 -183
- data/ext/java/nokogiri/internals/HtmlDomParserContext.java +0 -206
- data/ext/java/nokogiri/internals/NokogiriDocumentCache.java +0 -73
- data/ext/java/nokogiri/internals/NokogiriErrorHandler.java +0 -86
- data/ext/java/nokogiri/internals/NokogiriHandler.java +0 -327
- data/ext/java/nokogiri/internals/NokogiriHelpers.java +0 -582
- data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +0 -171
- data/ext/java/nokogiri/internals/NokogiriNamespaceContext.java +0 -118
- data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler.java +0 -74
- data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler4NekoHtml.java +0 -121
- data/ext/java/nokogiri/internals/NokogiriStrictErrorHandler.java +0 -79
- data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +0 -126
- data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +0 -56
- data/ext/java/nokogiri/internals/ParserContext.java +0 -278
- data/ext/java/nokogiri/internals/PushInputStream.java +0 -411
- data/ext/java/nokogiri/internals/ReaderNode.java +0 -474
- data/ext/java/nokogiri/internals/SaveContext.java +0 -288
- data/ext/java/nokogiri/internals/SchemaErrorHandler.java +0 -76
- data/ext/java/nokogiri/internals/XmlDeclHandler.java +0 -42
- data/ext/java/nokogiri/internals/XmlDomParser.java +0 -77
- data/ext/java/nokogiri/internals/XmlDomParserContext.java +0 -238
- data/ext/java/nokogiri/internals/XmlSaxParser.java +0 -65
- data/ext/java/nokogiri/internals/XsltExtensionFunction.java +0 -72
- data/lib/isorelax.jar +0 -0
- data/lib/jing.jar +0 -0
- data/lib/nekodtd.jar +0 -0
- data/lib/nekohtml.jar +0 -0
- data/lib/xercesImpl.jar +0 -0
@@ -1,529 +0,0 @@
|
|
1
|
-
/**
|
2
|
-
* (The MIT License)
|
3
|
-
*
|
4
|
-
* Copyright (c) 2008 - 2011:
|
5
|
-
*
|
6
|
-
* * {Aaron Patterson}[http://tenderlovemaking.com]
|
7
|
-
* * {Mike Dalessio}[http://mike.daless.io]
|
8
|
-
* * {Charles Nutter}[http://blog.headius.com]
|
9
|
-
* * {Sergio Arbeo}[http://www.serabe.com]
|
10
|
-
* * {Patrick Mahoney}[http://polycrystal.org]
|
11
|
-
* * {Yoko Harada}[http://yokolet.blogspot.com]
|
12
|
-
*
|
13
|
-
* Permission is hereby granted, free of charge, to any person obtaining
|
14
|
-
* a copy of this software and associated documentation files (the
|
15
|
-
* 'Software'), to deal in the Software without restriction, including
|
16
|
-
* without limitation the rights to use, copy, modify, merge, publish,
|
17
|
-
* distribute, sublicense, and/or sell copies of the Software, and to
|
18
|
-
* permit persons to whom the Software is furnished to do so, subject to
|
19
|
-
* the following conditions:
|
20
|
-
*
|
21
|
-
* The above copyright notice and this permission notice shall be
|
22
|
-
* included in all copies or substantial portions of the Software.
|
23
|
-
*
|
24
|
-
* THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
25
|
-
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
26
|
-
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
27
|
-
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
28
|
-
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
29
|
-
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
30
|
-
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
31
|
-
*/
|
32
|
-
|
33
|
-
package nokogiri;
|
34
|
-
|
35
|
-
import static nokogiri.internals.NokogiriHelpers.getCachedNodeOrCreate;
|
36
|
-
import static nokogiri.internals.NokogiriHelpers.getLocalNameForNamespace;
|
37
|
-
import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
|
38
|
-
import static nokogiri.internals.NokogiriHelpers.isNamespace;
|
39
|
-
import static nokogiri.internals.NokogiriHelpers.rubyStringToString;
|
40
|
-
import static nokogiri.internals.NokogiriHelpers.stringOrNil;
|
41
|
-
|
42
|
-
import javax.xml.parsers.DocumentBuilderFactory;
|
43
|
-
import javax.xml.parsers.ParserConfigurationException;
|
44
|
-
|
45
|
-
import nokogiri.internals.NokogiriHelpers;
|
46
|
-
import nokogiri.internals.NokogiriNamespaceCache;
|
47
|
-
import nokogiri.internals.SaveContext;
|
48
|
-
import nokogiri.internals.XmlDomParserContext;
|
49
|
-
|
50
|
-
import org.jruby.Ruby;
|
51
|
-
import org.jruby.RubyClass;
|
52
|
-
import org.jruby.RubyFixnum;
|
53
|
-
import org.jruby.RubyNil;
|
54
|
-
import org.jruby.anno.JRubyClass;
|
55
|
-
import org.jruby.anno.JRubyMethod;
|
56
|
-
import org.jruby.javasupport.util.RuntimeHelpers;
|
57
|
-
import org.jruby.runtime.Arity;
|
58
|
-
import org.jruby.runtime.ThreadContext;
|
59
|
-
import org.jruby.runtime.builtin.IRubyObject;
|
60
|
-
import org.w3c.dom.Attr;
|
61
|
-
import org.w3c.dom.Document;
|
62
|
-
import org.w3c.dom.NamedNodeMap;
|
63
|
-
import org.w3c.dom.Node;
|
64
|
-
import org.w3c.dom.NodeList;
|
65
|
-
|
66
|
-
/**
|
67
|
-
* Class for Nokogiri::XML::Document
|
68
|
-
*
|
69
|
-
* @author sergio
|
70
|
-
* @author Yoko Harada <yokolet@gmail.com>
|
71
|
-
*/
|
72
|
-
|
73
|
-
@JRubyClass(name="Nokogiri::XML::Document", parent="Nokogiri::XML::Node")
|
74
|
-
public class XmlDocument extends XmlNode {
|
75
|
-
private NokogiriNamespaceCache nsCache;
|
76
|
-
|
77
|
-
/* UserData keys for storing extra info in the document node. */
|
78
|
-
public final static String DTD_RAW_DOCUMENT = "DTD_RAW_DOCUMENT";
|
79
|
-
protected final static String DTD_INTERNAL_SUBSET = "DTD_INTERNAL_SUBSET";
|
80
|
-
protected final static String DTD_EXTERNAL_SUBSET = "DTD_EXTERNAL_SUBSET";
|
81
|
-
|
82
|
-
/* DocumentBuilderFactory implementation class name. This needs to set a classloader into it.
|
83
|
-
* Setting an appropriate classloader resolves issue 380.
|
84
|
-
*/
|
85
|
-
private static final String DOCUMENTBUILDERFACTORY_IMPLE_NAME = "org.apache.xerces.jaxp.DocumentBuilderFactoryImpl";
|
86
|
-
|
87
|
-
private static boolean substituteEntities = false;
|
88
|
-
private static boolean loadExternalSubset = false; // TODO: Verify this.
|
89
|
-
|
90
|
-
/** cache variables */
|
91
|
-
protected IRubyObject encoding = null;
|
92
|
-
protected IRubyObject url = null;
|
93
|
-
|
94
|
-
public XmlDocument(Ruby ruby, RubyClass klazz) {
|
95
|
-
super(ruby, klazz, createNewDocument());
|
96
|
-
}
|
97
|
-
|
98
|
-
public XmlDocument(Ruby ruby, Document document) {
|
99
|
-
this(ruby, getNokogiriClass(ruby, "Nokogiri::XML::Document"), document);
|
100
|
-
}
|
101
|
-
|
102
|
-
public XmlDocument(Ruby ruby, RubyClass klass, Document document) {
|
103
|
-
super(ruby, klass, document);
|
104
|
-
nsCache = new NokogiriNamespaceCache();
|
105
|
-
createAndCacheNamespaces(ruby, document.getDocumentElement());
|
106
|
-
stabilizeTextContent(document);
|
107
|
-
setInstanceVariable("@decorators", ruby.getNil());
|
108
|
-
}
|
109
|
-
|
110
|
-
@Override
|
111
|
-
public void setNode(ThreadContext context, Node node) {
|
112
|
-
super.setNode(context, node);
|
113
|
-
if (nsCache == null) nsCache = new NokogiriNamespaceCache();
|
114
|
-
Ruby runtime = context.getRuntime();
|
115
|
-
if (node != null) {
|
116
|
-
Document document = (Document)node;
|
117
|
-
stabilizeTextContent(document);
|
118
|
-
createAndCacheNamespaces(runtime, document.getDocumentElement());
|
119
|
-
}
|
120
|
-
setInstanceVariable("@decorators", runtime.getNil());
|
121
|
-
}
|
122
|
-
|
123
|
-
public void setEncoding(IRubyObject encoding) {
|
124
|
-
this.encoding = encoding;
|
125
|
-
}
|
126
|
-
|
127
|
-
// not sure, but like attribute values, text value will be lost
|
128
|
-
// unless it is referred once before this document is used.
|
129
|
-
// this seems to happen only when the fragment is parsed from Node#in_context.
|
130
|
-
private void stabilizeTextContent(Document document) {
|
131
|
-
if (document.getDocumentElement() != null) document.getDocumentElement().getTextContent();
|
132
|
-
}
|
133
|
-
|
134
|
-
private void createAndCacheNamespaces(Ruby ruby, Node node) {
|
135
|
-
if (node == null) return;
|
136
|
-
if (node.hasAttributes()) {
|
137
|
-
NamedNodeMap nodeMap = node.getAttributes();
|
138
|
-
for (int i=0; i<nodeMap.getLength(); i++) {
|
139
|
-
Node n = nodeMap.item(i);
|
140
|
-
if (n instanceof Attr) {
|
141
|
-
Attr attr = (Attr)n;
|
142
|
-
String attrName = attr.getName();
|
143
|
-
// not sure, but need to get value always before document is referred.
|
144
|
-
// or lose attribute value
|
145
|
-
String attrValue = attr.getValue();
|
146
|
-
if (isNamespace(attrName)) {
|
147
|
-
String prefix = getLocalNameForNamespace(attrName);
|
148
|
-
prefix = prefix != null ? prefix : "";
|
149
|
-
nsCache.put(ruby, prefix, attrValue, node, this);
|
150
|
-
}
|
151
|
-
}
|
152
|
-
}
|
153
|
-
}
|
154
|
-
NodeList children = node.getChildNodes();
|
155
|
-
for (int i=0; i<children.getLength(); i++) {
|
156
|
-
createAndCacheNamespaces(ruby, children.item(i));
|
157
|
-
}
|
158
|
-
}
|
159
|
-
|
160
|
-
// When a document is created from fragment with a context (reference) document,
|
161
|
-
// namespace should be resolved based on the context document.
|
162
|
-
public XmlDocument(Ruby ruby, RubyClass klass, Document document, XmlDocument contextDoc) {
|
163
|
-
super(ruby, klass, document);
|
164
|
-
nsCache = contextDoc.getNamespaceCache();
|
165
|
-
XmlNamespace default_ns = nsCache.getDefault();
|
166
|
-
String default_href = rubyStringToString(default_ns.href(ruby.getCurrentContext()));
|
167
|
-
resolveNamespaceIfNecessary(ruby.getCurrentContext(), document.getDocumentElement(), default_href);
|
168
|
-
}
|
169
|
-
|
170
|
-
private void resolveNamespaceIfNecessary(ThreadContext context, Node node, String default_href) {
|
171
|
-
if (node == null) return;
|
172
|
-
String nodePrefix = node.getPrefix();
|
173
|
-
if (nodePrefix == null) { // default namespace
|
174
|
-
node.getOwnerDocument().renameNode(node, default_href, node.getNodeName());
|
175
|
-
} else {
|
176
|
-
XmlNamespace xmlNamespace = nsCache.get(nodePrefix);
|
177
|
-
String href = rubyStringToString(xmlNamespace.href(context));
|
178
|
-
node.getOwnerDocument().renameNode(node, href, node.getNodeName());
|
179
|
-
}
|
180
|
-
resolveNamespaceIfNecessary(context, node.getNextSibling(), default_href);
|
181
|
-
NodeList children = node.getChildNodes();
|
182
|
-
for (int i=0; i<children.getLength(); i++) {
|
183
|
-
resolveNamespaceIfNecessary(context, children.item(i), default_href);
|
184
|
-
}
|
185
|
-
}
|
186
|
-
|
187
|
-
public NokogiriNamespaceCache getNamespaceCache() {
|
188
|
-
return nsCache;
|
189
|
-
}
|
190
|
-
|
191
|
-
public void setNamespaceCache(NokogiriNamespaceCache nsCache) {
|
192
|
-
this.nsCache = nsCache;
|
193
|
-
}
|
194
|
-
|
195
|
-
public Document getDocument() {
|
196
|
-
return (Document) node;
|
197
|
-
}
|
198
|
-
|
199
|
-
@Override
|
200
|
-
protected IRubyObject getNodeName(ThreadContext context) {
|
201
|
-
if (name == null) name = context.getRuntime().newString("document");
|
202
|
-
return name;
|
203
|
-
}
|
204
|
-
|
205
|
-
public void setUrl(IRubyObject url) {
|
206
|
-
this.url = url;
|
207
|
-
}
|
208
|
-
|
209
|
-
protected IRubyObject getUrl() {
|
210
|
-
return this.url;
|
211
|
-
}
|
212
|
-
|
213
|
-
@JRubyMethod
|
214
|
-
public IRubyObject url(ThreadContext context) {
|
215
|
-
return getUrl();
|
216
|
-
}
|
217
|
-
|
218
|
-
protected static Document createNewDocument() {
|
219
|
-
try {
|
220
|
-
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(DOCUMENTBUILDERFACTORY_IMPLE_NAME, NokogiriService.class.getClassLoader());
|
221
|
-
return factory.newDocumentBuilder().newDocument();
|
222
|
-
} catch (ParserConfigurationException e) {
|
223
|
-
return null; // this will end is disaster...
|
224
|
-
}
|
225
|
-
}
|
226
|
-
|
227
|
-
/*
|
228
|
-
* call-seq:
|
229
|
-
* new(version = default)
|
230
|
-
*
|
231
|
-
* Create a new document with +version+ (defaults to "1.0")
|
232
|
-
*/
|
233
|
-
@JRubyMethod(name="new", meta = true, rest = true, required=0)
|
234
|
-
public static IRubyObject rbNew(ThreadContext context, IRubyObject klazz, IRubyObject[] args) {
|
235
|
-
XmlDocument xmlDocument = null;
|
236
|
-
try {
|
237
|
-
Document docNode = createNewDocument();
|
238
|
-
if ("Nokogiri::HTML::Document".equals(((RubyClass)klazz).getName())) {
|
239
|
-
xmlDocument = (XmlDocument) NokogiriService.HTML_DOCUMENT_ALLOCATOR.allocate(context.getRuntime(), (RubyClass) klazz);
|
240
|
-
xmlDocument.setNode(context, docNode);
|
241
|
-
} else {
|
242
|
-
// XML::Document and sublass
|
243
|
-
xmlDocument = (XmlDocument) NokogiriService.XML_DOCUMENT_ALLOCATOR.allocate(context.getRuntime(), (RubyClass) klazz);
|
244
|
-
xmlDocument.setNode(context, docNode);
|
245
|
-
}
|
246
|
-
} catch (Exception ex) {
|
247
|
-
throw context.getRuntime().newRuntimeError("couldn't create document: "+ex.toString());
|
248
|
-
}
|
249
|
-
|
250
|
-
RuntimeHelpers.invoke(context, xmlDocument, "initialize", args);
|
251
|
-
|
252
|
-
return xmlDocument;
|
253
|
-
}
|
254
|
-
|
255
|
-
@JRubyMethod(required=1, optional=4)
|
256
|
-
public IRubyObject create_entity(ThreadContext context, IRubyObject[] argv) {
|
257
|
-
// FIXME: Entity node should be create by some right way.
|
258
|
-
// this impl passes tests, but entity doesn't exists in DTD, which
|
259
|
-
// would cause validation failure.
|
260
|
-
if (argv.length == 0) throw context.getRuntime().newRuntimeError("Could not create entity");
|
261
|
-
String tagName = rubyStringToString(argv[0]);
|
262
|
-
Node n = this.getOwnerDocument().createElement(tagName);
|
263
|
-
return XmlEntityDecl.create(context, n, argv);
|
264
|
-
}
|
265
|
-
|
266
|
-
@Override
|
267
|
-
@JRubyMethod
|
268
|
-
public IRubyObject document(ThreadContext context) {
|
269
|
-
return this;
|
270
|
-
}
|
271
|
-
|
272
|
-
@JRubyMethod(name="encoding=")
|
273
|
-
public IRubyObject encoding_set(ThreadContext context, IRubyObject encoding) {
|
274
|
-
this.encoding = encoding;
|
275
|
-
return this;
|
276
|
-
}
|
277
|
-
|
278
|
-
@JRubyMethod
|
279
|
-
public IRubyObject encoding(ThreadContext context) {
|
280
|
-
if (this.encoding == null) {
|
281
|
-
if (getDocument().getXmlEncoding() == null) {
|
282
|
-
this.encoding = context.getRuntime().getNil();
|
283
|
-
} else {
|
284
|
-
this.encoding = context.getRuntime().newString(getDocument().getXmlEncoding());
|
285
|
-
}
|
286
|
-
}
|
287
|
-
|
288
|
-
return this.encoding;
|
289
|
-
}
|
290
|
-
|
291
|
-
@JRubyMethod(meta = true)
|
292
|
-
public static IRubyObject load_external_subsets_set(ThreadContext context, IRubyObject cls, IRubyObject value) {
|
293
|
-
XmlDocument.loadExternalSubset = value.isTrue();
|
294
|
-
return context.getRuntime().getNil();
|
295
|
-
}
|
296
|
-
|
297
|
-
/**
|
298
|
-
* TODO: handle encoding?
|
299
|
-
*
|
300
|
-
* @param args[0] a Ruby IO or StringIO
|
301
|
-
* @param args[1] url or nil
|
302
|
-
* @param args[2] encoding
|
303
|
-
* @param args[3] bitset of parser options
|
304
|
-
*/
|
305
|
-
public static IRubyObject newFromData(ThreadContext context,
|
306
|
-
IRubyObject klass,
|
307
|
-
IRubyObject[] args) {
|
308
|
-
Ruby ruby = context.getRuntime();
|
309
|
-
Arity.checkArgumentCount(ruby, args, 4, 4);
|
310
|
-
XmlDomParserContext ctx =
|
311
|
-
new XmlDomParserContext(ruby, args[2], args[3]);
|
312
|
-
ctx.setInputSource(context, args[0]);
|
313
|
-
return ctx.parse(context, klass, args[1]);
|
314
|
-
}
|
315
|
-
|
316
|
-
@JRubyMethod(meta = true, rest = true)
|
317
|
-
public static IRubyObject read_io(ThreadContext context,
|
318
|
-
IRubyObject klass,
|
319
|
-
IRubyObject[] args) {
|
320
|
-
return newFromData(context, klass, args);
|
321
|
-
}
|
322
|
-
|
323
|
-
@JRubyMethod(meta = true, rest = true)
|
324
|
-
public static IRubyObject read_memory(ThreadContext context,
|
325
|
-
IRubyObject klass,
|
326
|
-
IRubyObject[] args) {
|
327
|
-
return newFromData(context, klass, args);
|
328
|
-
}
|
329
|
-
|
330
|
-
/** not a JRubyMethod */
|
331
|
-
public static IRubyObject read_memory(ThreadContext context,
|
332
|
-
IRubyObject[] args) {
|
333
|
-
return read_memory(context,
|
334
|
-
getNokogiriClass(context.getRuntime(), "Nokogiri::XML::Document"),
|
335
|
-
args);
|
336
|
-
}
|
337
|
-
|
338
|
-
@JRubyMethod(name="remove_namespaces!")
|
339
|
-
public IRubyObject remove_namespaces(ThreadContext context) {
|
340
|
-
removeNamespceRecursively(context, this);
|
341
|
-
nsCache.clear();
|
342
|
-
return this;
|
343
|
-
}
|
344
|
-
|
345
|
-
private void removeNamespceRecursively(ThreadContext context, XmlNode xmlNode) {
|
346
|
-
Node node = xmlNode.node;
|
347
|
-
if (node.getNodeType() == Node.ELEMENT_NODE) {
|
348
|
-
node.setPrefix(null);
|
349
|
-
node.getOwnerDocument().renameNode(node, null, node.getLocalName());
|
350
|
-
NamedNodeMap attrs = node.getAttributes();
|
351
|
-
for (int i=0; i<attrs.getLength(); i++) {
|
352
|
-
Node attr = attrs.item(i);
|
353
|
-
attr.setPrefix(null);
|
354
|
-
attr.getOwnerDocument().renameNode(attr, null, attr.getLocalName());
|
355
|
-
}
|
356
|
-
}
|
357
|
-
XmlNodeSet nodeSet = (XmlNodeSet) xmlNode.children(context);
|
358
|
-
for (long i=0; i < nodeSet.length(); i++) {
|
359
|
-
XmlNode childNode = (XmlNode)nodeSet.slice(context, RubyFixnum.newFixnum(context.getRuntime(), i));
|
360
|
-
removeNamespceRecursively(context, childNode);
|
361
|
-
}
|
362
|
-
}
|
363
|
-
|
364
|
-
@JRubyMethod
|
365
|
-
public IRubyObject root(ThreadContext context) {
|
366
|
-
Node rootNode = getDocument().getDocumentElement();
|
367
|
-
try {
|
368
|
-
Boolean isValid = (Boolean)rootNode.getUserData(NokogiriHelpers.VALID_ROOT_NODE);
|
369
|
-
if (!isValid) return context.getRuntime().getNil();
|
370
|
-
} catch (NullPointerException e) {
|
371
|
-
// does nothing since nil wasn't set to the root node before.
|
372
|
-
}
|
373
|
-
if (rootNode == null)
|
374
|
-
return context.getRuntime().getNil();
|
375
|
-
else
|
376
|
-
return getCachedNodeOrCreate(context.getRuntime(), rootNode);
|
377
|
-
}
|
378
|
-
|
379
|
-
@JRubyMethod(name="root=")
|
380
|
-
public IRubyObject root_set(ThreadContext context, IRubyObject newRoot_) {
|
381
|
-
// in case of document fragment, temporary root node should be deleted.
|
382
|
-
|
383
|
-
// Java can't have a root whose value is null. Instead of setting null,
|
384
|
-
// the method sets user data so that other methods are able to know the root
|
385
|
-
// should be nil.
|
386
|
-
if (newRoot_ instanceof RubyNil) {
|
387
|
-
getDocument().getDocumentElement().setUserData(NokogiriHelpers.VALID_ROOT_NODE, false, null);
|
388
|
-
return newRoot_;
|
389
|
-
}
|
390
|
-
XmlNode newRoot = asXmlNode(context, newRoot_);
|
391
|
-
|
392
|
-
IRubyObject root = root(context);
|
393
|
-
if (root.isNil()) {
|
394
|
-
Node newRootNode;
|
395
|
-
if (getDocument() == newRoot.getOwnerDocument()) {
|
396
|
-
newRootNode = newRoot.node;
|
397
|
-
} else {
|
398
|
-
// must copy otherwise newRoot may exist in two places
|
399
|
-
// with different owner document.
|
400
|
-
newRootNode = getDocument().importNode(newRoot.node, true);
|
401
|
-
}
|
402
|
-
add_child_node(context, getCachedNodeOrCreate(context.getRuntime(), newRootNode));
|
403
|
-
} else {
|
404
|
-
Node rootNode = asXmlNode(context, root).node;
|
405
|
-
((XmlNode)getCachedNodeOrCreate(context.getRuntime(), rootNode)).replace_node(context, newRoot);
|
406
|
-
}
|
407
|
-
|
408
|
-
return newRoot;
|
409
|
-
}
|
410
|
-
|
411
|
-
@JRubyMethod
|
412
|
-
public IRubyObject version(ThreadContext context) {
|
413
|
-
return stringOrNil(context.getRuntime(), getDocument().getXmlVersion());
|
414
|
-
}
|
415
|
-
|
416
|
-
@JRubyMethod(meta = true)
|
417
|
-
public static IRubyObject substitute_entities_set(ThreadContext context, IRubyObject cls, IRubyObject value) {
|
418
|
-
XmlDocument.substituteEntities = value.isTrue();
|
419
|
-
return context.getRuntime().getNil();
|
420
|
-
}
|
421
|
-
|
422
|
-
public IRubyObject getInternalSubset(ThreadContext context) {
|
423
|
-
IRubyObject dtd =
|
424
|
-
(IRubyObject) node.getUserData(DTD_INTERNAL_SUBSET);
|
425
|
-
|
426
|
-
if (dtd == null) {
|
427
|
-
if (getDocument().getDoctype() == null)
|
428
|
-
dtd = context.getRuntime().getNil();
|
429
|
-
else
|
430
|
-
dtd = XmlDtd.newFromInternalSubset(context.getRuntime(),
|
431
|
-
getDocument());
|
432
|
-
|
433
|
-
setInternalSubset(dtd);
|
434
|
-
}
|
435
|
-
|
436
|
-
return dtd;
|
437
|
-
}
|
438
|
-
|
439
|
-
/**
|
440
|
-
* Assumes XmlNode#internal_subset() has returned nil. (i.e. there
|
441
|
-
* is not already an internal subset).
|
442
|
-
*/
|
443
|
-
public IRubyObject createInternalSubset(ThreadContext context,
|
444
|
-
IRubyObject name,
|
445
|
-
IRubyObject external_id,
|
446
|
-
IRubyObject system_id) {
|
447
|
-
XmlDtd dtd = XmlDtd.newEmpty(context.getRuntime(),
|
448
|
-
this.getDocument(),
|
449
|
-
name, external_id, system_id);
|
450
|
-
setInternalSubset(dtd);
|
451
|
-
return dtd;
|
452
|
-
}
|
453
|
-
|
454
|
-
protected void setInternalSubset(IRubyObject data) {
|
455
|
-
node.setUserData(DTD_INTERNAL_SUBSET, data, null);
|
456
|
-
}
|
457
|
-
|
458
|
-
public IRubyObject getExternalSubset(ThreadContext context) {
|
459
|
-
IRubyObject dtd = (IRubyObject)
|
460
|
-
node.getUserData(DTD_EXTERNAL_SUBSET);
|
461
|
-
|
462
|
-
if (dtd == null) {
|
463
|
-
dtd = XmlDtd.newFromExternalSubset(context.getRuntime(),
|
464
|
-
getDocument());
|
465
|
-
setExternalSubset(dtd);
|
466
|
-
}
|
467
|
-
|
468
|
-
return dtd;
|
469
|
-
}
|
470
|
-
|
471
|
-
/**
|
472
|
-
* Assumes XmlNode#external_subset() has returned nil. (i.e. there
|
473
|
-
* is not already an external subset).
|
474
|
-
*/
|
475
|
-
public IRubyObject createExternalSubset(ThreadContext context,
|
476
|
-
IRubyObject name,
|
477
|
-
IRubyObject external_id,
|
478
|
-
IRubyObject system_id) {
|
479
|
-
XmlDtd dtd = XmlDtd.newEmpty(context.getRuntime(),
|
480
|
-
this.getDocument(),
|
481
|
-
name, external_id, system_id);
|
482
|
-
setExternalSubset(dtd);
|
483
|
-
return dtd;
|
484
|
-
}
|
485
|
-
|
486
|
-
protected void setExternalSubset(IRubyObject data) {
|
487
|
-
node.setUserData(DTD_EXTERNAL_SUBSET, data, null);
|
488
|
-
}
|
489
|
-
|
490
|
-
//public IRubyObject createE
|
491
|
-
|
492
|
-
@Override
|
493
|
-
public void saveContent(ThreadContext context, SaveContext ctx) {
|
494
|
-
if(!ctx.noDecl()) {
|
495
|
-
ctx.append("<?xml version=\"");
|
496
|
-
ctx.append(getDocument().getXmlVersion());
|
497
|
-
ctx.append("\"");
|
498
|
-
// if(!cur.encoding(context).isNil()) {
|
499
|
-
// ctx.append(" encoding=");
|
500
|
-
// ctx.append(cur.encoding(context).asJavaString());
|
501
|
-
// }
|
502
|
-
|
503
|
-
String encoding = ctx.getEncoding();
|
504
|
-
|
505
|
-
if(encoding == null &&
|
506
|
-
!encoding(context).isNil()) {
|
507
|
-
encoding = encoding(context).convertToString().asJavaString();
|
508
|
-
}
|
509
|
-
|
510
|
-
if(encoding != null) {
|
511
|
-
ctx.append(" encoding=\"");
|
512
|
-
ctx.append(encoding);
|
513
|
-
ctx.append("\"");
|
514
|
-
}
|
515
|
-
|
516
|
-
//ctx.append(" standalone=\"");
|
517
|
-
//ctx.append(getDocument().getXmlStandalone() ? "yes" : "no");
|
518
|
-
ctx.append("?>\n");
|
519
|
-
}
|
520
|
-
|
521
|
-
IRubyObject maybeRoot = root(context);
|
522
|
-
if (maybeRoot.isNil())
|
523
|
-
throw context.getRuntime().newRuntimeError("no root document");
|
524
|
-
|
525
|
-
XmlNode root = (XmlNode) maybeRoot;
|
526
|
-
root.saveContent(context, ctx);
|
527
|
-
ctx.append("\n");
|
528
|
-
}
|
529
|
-
}
|