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,582 +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.internals;
|
34
|
-
|
35
|
-
import java.io.UnsupportedEncodingException;
|
36
|
-
import java.nio.ByteBuffer;
|
37
|
-
import java.nio.charset.Charset;
|
38
|
-
|
39
|
-
import nokogiri.NokogiriService;
|
40
|
-
import nokogiri.XmlAttr;
|
41
|
-
import nokogiri.XmlCdata;
|
42
|
-
import nokogiri.XmlComment;
|
43
|
-
import nokogiri.XmlDocument;
|
44
|
-
import nokogiri.XmlElement;
|
45
|
-
import nokogiri.XmlNamespace;
|
46
|
-
import nokogiri.XmlNode;
|
47
|
-
import nokogiri.XmlText;
|
48
|
-
|
49
|
-
import org.jruby.Ruby;
|
50
|
-
import org.jruby.RubyArray;
|
51
|
-
import org.jruby.RubyClass;
|
52
|
-
import org.jruby.RubyEncoding;
|
53
|
-
import org.jruby.RubyString;
|
54
|
-
import org.jruby.runtime.builtin.IRubyObject;
|
55
|
-
import org.jruby.util.ByteList;
|
56
|
-
import org.w3c.dom.Attr;
|
57
|
-
import org.w3c.dom.NamedNodeMap;
|
58
|
-
import org.w3c.dom.Node;
|
59
|
-
import org.w3c.dom.NodeList;
|
60
|
-
|
61
|
-
/**
|
62
|
-
* A class for various utility methods.
|
63
|
-
*
|
64
|
-
* @author serabe
|
65
|
-
* @author Patrick Mahoney <pat@polycrystal.org>
|
66
|
-
* @author Yoko Harada <yokolet@gmail.com>
|
67
|
-
*/
|
68
|
-
public class NokogiriHelpers {
|
69
|
-
public static final String CACHED_NODE = "NOKOGIRI_CACHED_NODE";
|
70
|
-
public static final String VALID_ROOT_NODE = "NOKOGIRI_VALIDE_ROOT_NODE";
|
71
|
-
|
72
|
-
public static XmlNode getCachedNode(Node node) {
|
73
|
-
return (XmlNode) node.getUserData(CACHED_NODE);
|
74
|
-
}
|
75
|
-
|
76
|
-
/**
|
77
|
-
* Get the XmlNode associated with the underlying
|
78
|
-
* <code>node</code>. Creates a new XmlNode (or appropriate subclass)
|
79
|
-
* or XmlNamespace wrapping <code>node</code> if there is no cached
|
80
|
-
* value.
|
81
|
-
*/
|
82
|
-
public static IRubyObject getCachedNodeOrCreate(Ruby ruby, Node node) {
|
83
|
-
if(node == null) return ruby.getNil();
|
84
|
-
if (node.getNodeType() == Node.ATTRIBUTE_NODE && isNamespace(node.getNodeName())) {
|
85
|
-
XmlDocument xmlDocument = (XmlDocument)node.getOwnerDocument().getUserData(CACHED_NODE);
|
86
|
-
String prefix = getLocalNameForNamespace(((Attr)node).getName());
|
87
|
-
prefix = prefix != null ? prefix : "";
|
88
|
-
String href = ((Attr)node).getValue();
|
89
|
-
XmlNamespace xmlNamespace = xmlDocument.getNamespaceCache().get(prefix, href);
|
90
|
-
if (xmlNamespace == null) {
|
91
|
-
return xmlDocument.getNamespaceCache().put(ruby, prefix, ((Attr)node).getValue(), node, xmlDocument);
|
92
|
-
}
|
93
|
-
}
|
94
|
-
XmlNode xmlNode = getCachedNode(node);
|
95
|
-
if(xmlNode == null) {
|
96
|
-
xmlNode = (XmlNode)constructNode(ruby, node);
|
97
|
-
node.setUserData(CACHED_NODE, xmlNode, null);
|
98
|
-
}
|
99
|
-
return xmlNode;
|
100
|
-
}
|
101
|
-
|
102
|
-
/**
|
103
|
-
* Construct a new XmlNode wrapping <code>node</code>. The proper
|
104
|
-
* subclass of XmlNode is chosen based on the type of
|
105
|
-
* <code>node</code>.
|
106
|
-
*/
|
107
|
-
public static IRubyObject constructNode(Ruby runtime, Node node) {
|
108
|
-
if (node == null) return runtime.getNil();
|
109
|
-
// this is slow; need a way to cache nokogiri classes/modules somewhere
|
110
|
-
switch (node.getNodeType()) {
|
111
|
-
case Node.ELEMENT_NODE:
|
112
|
-
XmlElement xmlElement = (XmlElement) NokogiriService.XML_ELEMENT_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Element"));
|
113
|
-
xmlElement.setNode(runtime.getCurrentContext(), node);
|
114
|
-
return xmlElement;
|
115
|
-
case Node.ATTRIBUTE_NODE:
|
116
|
-
XmlAttr xmlAttr = (XmlAttr) NokogiriService.XML_ATTR_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Attr"));
|
117
|
-
xmlAttr.setNode(runtime.getCurrentContext(), node);
|
118
|
-
return xmlAttr;
|
119
|
-
case Node.TEXT_NODE:
|
120
|
-
XmlText xmlText = (XmlText) NokogiriService.XML_TEXT_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Text"));
|
121
|
-
xmlText.setNode(runtime.getCurrentContext(), node);
|
122
|
-
return xmlText;
|
123
|
-
case Node.COMMENT_NODE:
|
124
|
-
XmlComment xmlComment = (XmlComment) NokogiriService.XML_COMMENT_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Comment"));
|
125
|
-
xmlComment.setNode(runtime.getCurrentContext(), node);
|
126
|
-
return xmlComment;
|
127
|
-
case Node.ENTITY_NODE:
|
128
|
-
return new XmlNode(runtime, getNokogiriClass(runtime, "Nokogiri::XML::EntityDecl"), node);
|
129
|
-
case Node.CDATA_SECTION_NODE:
|
130
|
-
XmlCdata xmlCdata = (XmlCdata) NokogiriService.XML_CDATA_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::CDATA"));
|
131
|
-
xmlCdata.setNode(runtime.getCurrentContext(), node);
|
132
|
-
return xmlCdata;
|
133
|
-
case Node.DOCUMENT_NODE:
|
134
|
-
XmlDocument xmlDocument = (XmlDocument) NokogiriService.XML_DOCUMENT_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Document"));
|
135
|
-
xmlDocument.setNode(runtime.getCurrentContext(), node);
|
136
|
-
return xmlDocument;
|
137
|
-
default:
|
138
|
-
XmlNode xmlNode = (XmlNode) NokogiriService.XML_NODE_ALLOCATOR.allocate(runtime, getNokogiriClass(runtime, "Nokogiri::XML::Node"));
|
139
|
-
xmlNode.setNode(runtime.getCurrentContext(), node);
|
140
|
-
return xmlNode;
|
141
|
-
}
|
142
|
-
}
|
143
|
-
|
144
|
-
public static RubyClass getNokogiriClass(Ruby ruby, String name) {
|
145
|
-
return NokogiriService.nokogiriClassCache.get(name);
|
146
|
-
}
|
147
|
-
|
148
|
-
public static IRubyObject stringOrNil(Ruby runtime, String s) {
|
149
|
-
if (s == null) return runtime.getNil();
|
150
|
-
return RubyString.newString(runtime, s);
|
151
|
-
}
|
152
|
-
|
153
|
-
public static IRubyObject stringOrBlank(Ruby runtime, String s) {
|
154
|
-
if (s == null) return runtime.newString();
|
155
|
-
return RubyString.newString(runtime, s);
|
156
|
-
}
|
157
|
-
|
158
|
-
/**
|
159
|
-
* Convert <code>s</code> to a RubyString, or if s is null or
|
160
|
-
* empty return RubyNil.
|
161
|
-
*/
|
162
|
-
public static IRubyObject nonEmptyStringOrNil(Ruby runtime, String s) {
|
163
|
-
if (s == null || s.length() == 0) return runtime.getNil();
|
164
|
-
return RubyString.newString(runtime, s);
|
165
|
-
}
|
166
|
-
|
167
|
-
/**
|
168
|
-
* Return the prefix of a qualified name like "prefix:local".
|
169
|
-
* Returns null if there is no prefix.
|
170
|
-
*/
|
171
|
-
public static String getPrefix(String qName) {
|
172
|
-
if (qName == null) return null;
|
173
|
-
|
174
|
-
int pos = qName.indexOf(':');
|
175
|
-
if (pos > 0)
|
176
|
-
return qName.substring(0, pos);
|
177
|
-
else
|
178
|
-
return null;
|
179
|
-
}
|
180
|
-
|
181
|
-
/**
|
182
|
-
* Return the local part of a qualified name like "prefix:local".
|
183
|
-
* Returns <code>qName</code> if there is no prefix.
|
184
|
-
*/
|
185
|
-
public static String getLocalPart(String qName) {
|
186
|
-
if (qName == null) return null;
|
187
|
-
|
188
|
-
int pos = qName.indexOf(':');
|
189
|
-
if (pos > 0)
|
190
|
-
return qName.substring(pos + 1);
|
191
|
-
else
|
192
|
-
return qName;
|
193
|
-
}
|
194
|
-
|
195
|
-
public static String getLocalNameForNamespace(String name) {
|
196
|
-
String localName = getLocalPart(name);
|
197
|
-
return ("xmlns".equals(localName)) ? null : localName;
|
198
|
-
}
|
199
|
-
|
200
|
-
private static Charset utf8 = null;
|
201
|
-
|
202
|
-
private static Charset getCharsetUTF8() {
|
203
|
-
if (utf8 == null) utf8 = Charset.forName("UTF-8");
|
204
|
-
return utf8;
|
205
|
-
}
|
206
|
-
|
207
|
-
/**
|
208
|
-
* Converts a RubyString in to a Java String. Assumes the
|
209
|
-
* RubyString is encoded as UTF-8. This is generally the case for
|
210
|
-
* RubyStrings created with getRuntime().newString("java string").
|
211
|
-
* It also seems to be the case for strings created within Ruby
|
212
|
-
* where $KCODE has not been set.
|
213
|
-
*
|
214
|
-
* Note that RubyString#toString() decodes the string data as
|
215
|
-
* ISO-8859-1 (See org.jruby.util.ByteList.java). This is not
|
216
|
-
* what you want if you have any multibyte characters in your
|
217
|
-
* UTF-8 string.
|
218
|
-
*
|
219
|
-
* FIXME: This really needs to be more robust in terms of
|
220
|
-
* detecting the encoding and properly converting to a Java
|
221
|
-
* String. It's unfortunate that RubyString#toString() doesn't do
|
222
|
-
* this for us.
|
223
|
-
*/
|
224
|
-
public static String rubyStringToString(IRubyObject str) {
|
225
|
-
//return rubyStringToString(str.convertToString());
|
226
|
-
return toJavaString(str.convertToString());
|
227
|
-
}
|
228
|
-
|
229
|
-
private static String toJavaString(RubyString str) {
|
230
|
-
ByteList value = str.getByteList();
|
231
|
-
try {
|
232
|
-
if (str.getRuntime().is1_9()) {
|
233
|
-
return new String(value.getUnsafeBytes(), value.begin(), value.length(), str.getEncoding().toString());
|
234
|
-
}
|
235
|
-
return RubyEncoding.decodeUTF8(value.getUnsafeBytes(), value.begin(), value.length());
|
236
|
-
} catch (UnsupportedEncodingException uee) {
|
237
|
-
return str.toString();
|
238
|
-
}
|
239
|
-
}
|
240
|
-
|
241
|
-
public static String rubyStringToString(RubyString str) {
|
242
|
-
ByteList byteList = str.getByteList();
|
243
|
-
byte[] data = byteList.unsafeBytes();
|
244
|
-
int offset = byteList.begin();
|
245
|
-
int len = byteList.length();
|
246
|
-
ByteBuffer buf = ByteBuffer.wrap(data, offset, len);
|
247
|
-
return getCharsetUTF8().decode(buf).toString();
|
248
|
-
}
|
249
|
-
|
250
|
-
public static String getNodeCompletePath(Node node) {
|
251
|
-
|
252
|
-
Node cur, tmp, next;
|
253
|
-
|
254
|
-
// TODO: Rename buffer to path.
|
255
|
-
String buffer = "";
|
256
|
-
String sep;
|
257
|
-
String name;
|
258
|
-
|
259
|
-
int occur = 0;
|
260
|
-
boolean generic;
|
261
|
-
|
262
|
-
cur = node;
|
263
|
-
|
264
|
-
do {
|
265
|
-
name = "";
|
266
|
-
sep = "?";
|
267
|
-
occur = 0;
|
268
|
-
generic = false;
|
269
|
-
|
270
|
-
if(cur.getNodeType() == Node.DOCUMENT_NODE) {
|
271
|
-
if(buffer.startsWith("/")) break;
|
272
|
-
|
273
|
-
sep = "/";
|
274
|
-
next = null;
|
275
|
-
} else if(cur.getNodeType() == Node.ELEMENT_NODE) {
|
276
|
-
generic = false;
|
277
|
-
sep = "/";
|
278
|
-
|
279
|
-
name = cur.getLocalName();
|
280
|
-
if (name == null) name = cur.getNodeName();
|
281
|
-
if(cur.getNamespaceURI() != null) {
|
282
|
-
if(cur.getPrefix() != null) {
|
283
|
-
name = cur.getPrefix() + ":" + name;
|
284
|
-
} else {
|
285
|
-
generic = true;
|
286
|
-
name = "*";
|
287
|
-
}
|
288
|
-
}
|
289
|
-
|
290
|
-
next = cur.getParentNode();
|
291
|
-
|
292
|
-
/*
|
293
|
-
* Thumbler index computation
|
294
|
-
*/
|
295
|
-
|
296
|
-
tmp = cur.getPreviousSibling();
|
297
|
-
|
298
|
-
while(tmp != null) {
|
299
|
-
if((tmp.getNodeType() == Node.ELEMENT_NODE) &&
|
300
|
-
(generic || fullNamesMatch(tmp, cur))) {
|
301
|
-
occur++;
|
302
|
-
}
|
303
|
-
tmp = tmp.getPreviousSibling();
|
304
|
-
}
|
305
|
-
|
306
|
-
if(occur == 0) {
|
307
|
-
tmp = cur.getNextSibling();
|
308
|
-
|
309
|
-
while(tmp != null && occur == 0) {
|
310
|
-
if((tmp.getNodeType() == Node.ELEMENT_NODE) &&
|
311
|
-
(generic || fullNamesMatch(tmp,cur))) {
|
312
|
-
occur++;
|
313
|
-
}
|
314
|
-
tmp = tmp.getNextSibling();
|
315
|
-
}
|
316
|
-
|
317
|
-
if(occur != 0) occur = 1;
|
318
|
-
|
319
|
-
} else {
|
320
|
-
occur++;
|
321
|
-
}
|
322
|
-
} else if(cur.getNodeType() == Node.COMMENT_NODE) {
|
323
|
-
sep = "/";
|
324
|
-
name = "comment()";
|
325
|
-
next = cur.getParentNode();
|
326
|
-
|
327
|
-
/*
|
328
|
-
* Thumbler index computation.
|
329
|
-
*/
|
330
|
-
|
331
|
-
tmp = cur.getPreviousSibling();
|
332
|
-
|
333
|
-
while(tmp != null) {
|
334
|
-
if(tmp.getNodeType() == Node.COMMENT_NODE) {
|
335
|
-
occur++;
|
336
|
-
}
|
337
|
-
tmp = tmp.getPreviousSibling();
|
338
|
-
}
|
339
|
-
|
340
|
-
if(occur == 0) {
|
341
|
-
tmp = cur.getNextSibling();
|
342
|
-
while(tmp != null && occur == 0) {
|
343
|
-
if(tmp.getNodeType() == Node.COMMENT_NODE) {
|
344
|
-
occur++;
|
345
|
-
}
|
346
|
-
tmp = tmp.getNextSibling();
|
347
|
-
}
|
348
|
-
if(occur != 0) occur = 1;
|
349
|
-
} else {
|
350
|
-
occur = 1;
|
351
|
-
}
|
352
|
-
|
353
|
-
} else if(cur.getNodeType() == Node.TEXT_NODE ||
|
354
|
-
cur.getNodeType() == Node.CDATA_SECTION_NODE) {
|
355
|
-
// I'm here. gist:129
|
356
|
-
// http://gist.github.com/144923
|
357
|
-
|
358
|
-
sep = "/";
|
359
|
-
name = "text()";
|
360
|
-
next = cur.getParentNode();
|
361
|
-
|
362
|
-
/*
|
363
|
-
* Thumbler index computation.
|
364
|
-
*/
|
365
|
-
|
366
|
-
tmp = cur.getPreviousSibling();
|
367
|
-
while(tmp != null) {
|
368
|
-
if(tmp.getNodeType() == Node.TEXT_NODE ||
|
369
|
-
tmp.getNodeType() == Node.CDATA_SECTION_NODE) {
|
370
|
-
occur++;
|
371
|
-
}
|
372
|
-
tmp = tmp.getPreviousSibling();
|
373
|
-
}
|
374
|
-
|
375
|
-
if(occur == 0) {
|
376
|
-
tmp = cur.getNextSibling();
|
377
|
-
|
378
|
-
while(tmp != null && occur == 0) {
|
379
|
-
if(tmp.getNodeType() == Node.TEXT_NODE ||
|
380
|
-
tmp.getNodeType() == Node.CDATA_SECTION_NODE) {
|
381
|
-
occur++;
|
382
|
-
}
|
383
|
-
tmp = tmp.getNextSibling();
|
384
|
-
}
|
385
|
-
} else {
|
386
|
-
occur++;
|
387
|
-
}
|
388
|
-
|
389
|
-
} else if(cur.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE) {
|
390
|
-
sep = "/";
|
391
|
-
name = "processing-instruction('"+cur.getLocalName()+"')";
|
392
|
-
next = cur.getParentNode();
|
393
|
-
|
394
|
-
/*
|
395
|
-
* Thumbler index computation.
|
396
|
-
*/
|
397
|
-
|
398
|
-
tmp = cur.getParentNode();
|
399
|
-
|
400
|
-
while(tmp != null) {
|
401
|
-
if(tmp.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE &&
|
402
|
-
tmp.getLocalName().equals(cur.getLocalName())) {
|
403
|
-
occur++;
|
404
|
-
}
|
405
|
-
tmp = tmp.getPreviousSibling();
|
406
|
-
}
|
407
|
-
|
408
|
-
if(occur == 0) {
|
409
|
-
tmp = cur.getNextSibling();
|
410
|
-
|
411
|
-
while(tmp != null && occur == 0) {
|
412
|
-
if(tmp.getNodeType() == Node.PROCESSING_INSTRUCTION_NODE &&
|
413
|
-
tmp.getLocalName().equals(cur.getLocalName())){
|
414
|
-
occur++;
|
415
|
-
}
|
416
|
-
tmp = tmp.getNextSibling();
|
417
|
-
}
|
418
|
-
|
419
|
-
if(occur != 0) {
|
420
|
-
occur = 1;
|
421
|
-
}
|
422
|
-
|
423
|
-
} else {
|
424
|
-
occur++;
|
425
|
-
}
|
426
|
-
|
427
|
-
} else if(cur.getNodeType() == Node.ATTRIBUTE_NODE) {
|
428
|
-
sep = "/@";
|
429
|
-
name = cur.getLocalName();
|
430
|
-
|
431
|
-
if(cur.getNamespaceURI() != null) {
|
432
|
-
if(cur.getPrefix() != null) {
|
433
|
-
name = cur.getPrefix() + ":" + name;
|
434
|
-
}
|
435
|
-
}
|
436
|
-
|
437
|
-
next = ((Attr) cur).getOwnerElement();
|
438
|
-
|
439
|
-
} else {
|
440
|
-
next = cur.getParentNode();
|
441
|
-
}
|
442
|
-
|
443
|
-
if(occur == 0){
|
444
|
-
buffer = sep+name+buffer;
|
445
|
-
} else {
|
446
|
-
buffer = sep+name+"["+occur+"]"+buffer;
|
447
|
-
}
|
448
|
-
|
449
|
-
cur = next;
|
450
|
-
|
451
|
-
} while(cur != null);
|
452
|
-
|
453
|
-
return buffer;
|
454
|
-
}
|
455
|
-
|
456
|
-
protected static boolean compareTwoNodes(Node m, Node n) {
|
457
|
-
return nodesAreEqual(m.getLocalName(), n.getLocalName()) &&
|
458
|
-
nodesAreEqual(m.getPrefix(), n.getPrefix());
|
459
|
-
}
|
460
|
-
|
461
|
-
protected static boolean fullNamesMatch(Node a, Node b) {
|
462
|
-
return a.getNodeName().equals(b.getNodeName());
|
463
|
-
}
|
464
|
-
|
465
|
-
protected static String getFullName(Node n) {
|
466
|
-
String lname = n.getLocalName();
|
467
|
-
String prefix = n.getPrefix();
|
468
|
-
if (lname != null) {
|
469
|
-
if (prefix != null)
|
470
|
-
return prefix + ":" + lname;
|
471
|
-
else
|
472
|
-
return lname;
|
473
|
-
} else {
|
474
|
-
return n.getNodeName();
|
475
|
-
}
|
476
|
-
}
|
477
|
-
|
478
|
-
private static boolean nodesAreEqual(Object a, Object b) {
|
479
|
-
return (((a == null) && (a == null)) ||
|
480
|
-
(a != null) && (b != null) &&
|
481
|
-
(b.equals(a)));
|
482
|
-
}
|
483
|
-
|
484
|
-
public static String encodeJavaString(String s) {
|
485
|
-
|
486
|
-
// From entities.c
|
487
|
-
s = s.replaceAll("&", "&");
|
488
|
-
s = s.replaceAll("<", "<");
|
489
|
-
s = s.replaceAll(">", ">");
|
490
|
-
// s = s.replaceAll("\"", """);
|
491
|
-
return s.replaceAll("\r", " ");
|
492
|
-
}
|
493
|
-
|
494
|
-
public static String decodeJavaString(String s) {
|
495
|
-
s = s.replaceAll("&", "&");
|
496
|
-
s = s.replaceAll("<", "<");
|
497
|
-
s = s.replaceAll(">", ">");
|
498
|
-
return s.replaceAll(" ", "\r");
|
499
|
-
}
|
500
|
-
|
501
|
-
public static boolean isXmlEscaped(String s) {
|
502
|
-
if (s == null) return true;
|
503
|
-
if (s.contains("<") || s.contains(">") || s.contains("\r")) return false;
|
504
|
-
if (s.contains("&") && !s.contains("&")) return false;
|
505
|
-
return true;
|
506
|
-
}
|
507
|
-
|
508
|
-
public static String getNodeName(Node node) {
|
509
|
-
if(node == null) { System.out.println("node is null"); return ""; }
|
510
|
-
String name = node.getNodeName();
|
511
|
-
if(name == null) { System.out.println("name is null"); return ""; }
|
512
|
-
if(name.equals("#document")) {
|
513
|
-
return "document";
|
514
|
-
} else if(name.equals("#text")) {
|
515
|
-
return "text";
|
516
|
-
} else {
|
517
|
-
name = getLocalPart(name);
|
518
|
-
return (name == null) ? "" : name;
|
519
|
-
}
|
520
|
-
}
|
521
|
-
|
522
|
-
public static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/";
|
523
|
-
public static boolean isNamespace(Node node) {
|
524
|
-
return (XMLNS_URI.equals(node.getNamespaceURI()) ||
|
525
|
-
isNamespace(node.getNodeName()));
|
526
|
-
}
|
527
|
-
|
528
|
-
public static boolean isNamespace(String nodeName) {
|
529
|
-
return (nodeName.equals("xmlns") || nodeName.startsWith("xmlns:"));
|
530
|
-
}
|
531
|
-
|
532
|
-
public static boolean isNonDefaultNamespace(Node node) {
|
533
|
-
return (isNamespace(node) && ! "xmlns".equals(node.getNodeName()));
|
534
|
-
}
|
535
|
-
|
536
|
-
public static boolean isXmlBase(String attrName) {
|
537
|
-
return "xml:base".equals(attrName) || "xlink:href".equals(attrName);
|
538
|
-
}
|
539
|
-
|
540
|
-
public static String newQName(String newPrefix, Node node) {
|
541
|
-
if(newPrefix == null) {
|
542
|
-
return node.getLocalName();
|
543
|
-
} else {
|
544
|
-
return newPrefix + ":" + node.getLocalName();
|
545
|
-
}
|
546
|
-
}
|
547
|
-
|
548
|
-
public static RubyArray nodeListToRubyArray(Ruby ruby, NodeList nodes) {
|
549
|
-
RubyArray array = RubyArray.newArray(ruby, nodes.getLength());
|
550
|
-
return nodeListToRubyArray(ruby, nodes, array);
|
551
|
-
}
|
552
|
-
|
553
|
-
public static RubyArray nodeListToRubyArray(Ruby ruby, NodeList nodes, RubyArray array) {
|
554
|
-
for(int i = 0; i < nodes.getLength(); i++) {
|
555
|
-
array.append(NokogiriHelpers.getCachedNodeOrCreate(ruby, nodes.item(i)));
|
556
|
-
}
|
557
|
-
return array;
|
558
|
-
}
|
559
|
-
|
560
|
-
public static RubyArray nodeArrayToRubyArray(Ruby ruby, Node[] nodes) {
|
561
|
-
RubyArray n = RubyArray.newArray(ruby, nodes.length);
|
562
|
-
for(int i = 0; i < nodes.length; i++) {
|
563
|
-
n.append(NokogiriHelpers.getCachedNodeOrCreate(ruby, nodes[i]));
|
564
|
-
}
|
565
|
-
return n;
|
566
|
-
}
|
567
|
-
|
568
|
-
public static RubyArray namedNodeMapToRubyArray(Ruby ruby, NamedNodeMap map) {
|
569
|
-
RubyArray n = RubyArray.newArray(ruby, map.getLength());
|
570
|
-
for(int i = 0; i < map.getLength(); i++) {
|
571
|
-
n.append(NokogiriHelpers.getCachedNodeOrCreate(ruby, map.item(i)));
|
572
|
-
}
|
573
|
-
return n;
|
574
|
-
}
|
575
|
-
|
576
|
-
public static String guessEncoding(Ruby ruby) {
|
577
|
-
String name = null;
|
578
|
-
if (name == null) name = System.getProperty("file.encoding");
|
579
|
-
if (name == null) name = "UTF-8";
|
580
|
-
return name;
|
581
|
-
}
|
582
|
-
}
|