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.

Files changed (107) hide show
  1. data/.gemtest +0 -0
  2. data/CHANGELOG.ja.rdoc +34 -0
  3. data/CHANGELOG.rdoc +40 -1
  4. data/Manifest.txt +11 -2
  5. data/README.rdoc +1 -1
  6. data/Rakefile +100 -104
  7. data/bin/nokogiri +1 -2
  8. data/ext/nokogiri/nokogiri.c +24 -1
  9. data/ext/nokogiri/xml_io.c +32 -7
  10. data/ext/nokogiri/xml_node.c +14 -13
  11. data/ext/nokogiri/xml_sax_parser.c +9 -4
  12. data/ext/nokogiri/xslt_stylesheet.c +7 -1
  13. data/lib/nokogiri.rb +3 -22
  14. data/lib/nokogiri/css.rb +4 -0
  15. data/lib/nokogiri/html/document.rb +10 -14
  16. data/lib/nokogiri/version.rb +76 -23
  17. data/lib/nokogiri/xml/builder.rb +7 -0
  18. data/lib/nokogiri/xml/document.rb +17 -1
  19. data/lib/nokogiri/xml/document_fragment.rb +14 -0
  20. data/lib/nokogiri/xml/node.rb +36 -28
  21. data/lib/nokogiri/xml/node/save_options.rb +17 -1
  22. data/lib/nokogiri/xml/node_set.rb +7 -0
  23. data/lib/nokogiri/xml/parse_options.rb +8 -0
  24. data/lib/nokogiri/xml/reader.rb +6 -6
  25. data/lib/nokogiri/xml/schema.rb +7 -1
  26. data/nokogiri_help_responses.md +40 -0
  27. data/tasks/cross_compile.rb +134 -159
  28. data/tasks/nokogiri.org.rb +18 -0
  29. data/tasks/test.rb +1 -1
  30. data/test/files/encoding.html +82 -0
  31. data/test/files/encoding.xhtml +84 -0
  32. data/test/files/metacharset.html +10 -0
  33. data/test/files/noencoding.html +47 -0
  34. data/test/helper.rb +2 -0
  35. data/test/html/test_document.rb +15 -0
  36. data/test/html/test_document_encoding.rb +13 -0
  37. data/test/test_memory_leak.rb +20 -0
  38. data/test/test_reader.rb +22 -0
  39. data/test/test_xslt_transforms.rb +6 -2
  40. data/test/xml/node/test_save_options.rb +10 -2
  41. data/test/xml/test_builder.rb +17 -0
  42. data/test/xml/test_document.rb +22 -0
  43. data/test/xml/test_node.rb +19 -1
  44. data/test/xml/test_node_reparenting.rb +16 -3
  45. data/test/xml/test_node_set.rb +34 -0
  46. data/test/xml/test_schema.rb +5 -0
  47. data/test/xslt/test_exception_handling.rb +37 -0
  48. metadata +185 -157
  49. data/deps.rip +0 -5
  50. data/ext/java/nokogiri/EncodingHandler.java +0 -124
  51. data/ext/java/nokogiri/HtmlDocument.java +0 -149
  52. data/ext/java/nokogiri/HtmlElementDescription.java +0 -145
  53. data/ext/java/nokogiri/HtmlEntityLookup.java +0 -79
  54. data/ext/java/nokogiri/HtmlSaxParserContext.java +0 -259
  55. data/ext/java/nokogiri/NokogiriService.java +0 -535
  56. data/ext/java/nokogiri/XmlAttr.java +0 -191
  57. data/ext/java/nokogiri/XmlAttributeDecl.java +0 -130
  58. data/ext/java/nokogiri/XmlCdata.java +0 -91
  59. data/ext/java/nokogiri/XmlComment.java +0 -86
  60. data/ext/java/nokogiri/XmlDocument.java +0 -529
  61. data/ext/java/nokogiri/XmlDocumentFragment.java +0 -217
  62. data/ext/java/nokogiri/XmlDtd.java +0 -467
  63. data/ext/java/nokogiri/XmlElement.java +0 -222
  64. data/ext/java/nokogiri/XmlElementContent.java +0 -382
  65. data/ext/java/nokogiri/XmlElementDecl.java +0 -148
  66. data/ext/java/nokogiri/XmlEntityDecl.java +0 -162
  67. data/ext/java/nokogiri/XmlEntityReference.java +0 -75
  68. data/ext/java/nokogiri/XmlNamespace.java +0 -128
  69. data/ext/java/nokogiri/XmlNode.java +0 -1399
  70. data/ext/java/nokogiri/XmlNodeSet.java +0 -311
  71. data/ext/java/nokogiri/XmlProcessingInstruction.java +0 -103
  72. data/ext/java/nokogiri/XmlReader.java +0 -411
  73. data/ext/java/nokogiri/XmlRelaxng.java +0 -144
  74. data/ext/java/nokogiri/XmlSaxParserContext.java +0 -367
  75. data/ext/java/nokogiri/XmlSaxPushParser.java +0 -184
  76. data/ext/java/nokogiri/XmlSchema.java +0 -319
  77. data/ext/java/nokogiri/XmlSyntaxError.java +0 -119
  78. data/ext/java/nokogiri/XmlText.java +0 -136
  79. data/ext/java/nokogiri/XmlXpathContext.java +0 -179
  80. data/ext/java/nokogiri/XsltStylesheet.java +0 -183
  81. data/ext/java/nokogiri/internals/HtmlDomParserContext.java +0 -206
  82. data/ext/java/nokogiri/internals/NokogiriDocumentCache.java +0 -73
  83. data/ext/java/nokogiri/internals/NokogiriErrorHandler.java +0 -86
  84. data/ext/java/nokogiri/internals/NokogiriHandler.java +0 -327
  85. data/ext/java/nokogiri/internals/NokogiriHelpers.java +0 -582
  86. data/ext/java/nokogiri/internals/NokogiriNamespaceCache.java +0 -171
  87. data/ext/java/nokogiri/internals/NokogiriNamespaceContext.java +0 -118
  88. data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler.java +0 -74
  89. data/ext/java/nokogiri/internals/NokogiriNonStrictErrorHandler4NekoHtml.java +0 -121
  90. data/ext/java/nokogiri/internals/NokogiriStrictErrorHandler.java +0 -79
  91. data/ext/java/nokogiri/internals/NokogiriXPathFunction.java +0 -126
  92. data/ext/java/nokogiri/internals/NokogiriXPathFunctionResolver.java +0 -56
  93. data/ext/java/nokogiri/internals/ParserContext.java +0 -278
  94. data/ext/java/nokogiri/internals/PushInputStream.java +0 -411
  95. data/ext/java/nokogiri/internals/ReaderNode.java +0 -474
  96. data/ext/java/nokogiri/internals/SaveContext.java +0 -288
  97. data/ext/java/nokogiri/internals/SchemaErrorHandler.java +0 -76
  98. data/ext/java/nokogiri/internals/XmlDeclHandler.java +0 -42
  99. data/ext/java/nokogiri/internals/XmlDomParser.java +0 -77
  100. data/ext/java/nokogiri/internals/XmlDomParserContext.java +0 -238
  101. data/ext/java/nokogiri/internals/XmlSaxParser.java +0 -65
  102. data/ext/java/nokogiri/internals/XsltExtensionFunction.java +0 -72
  103. data/lib/isorelax.jar +0 -0
  104. data/lib/jing.jar +0 -0
  105. data/lib/nekodtd.jar +0 -0
  106. data/lib/nekohtml.jar +0 -0
  107. 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("&", "&amp;");
488
- s = s.replaceAll("<", "&lt;");
489
- s = s.replaceAll(">", "&gt;");
490
- // s = s.replaceAll("\"", "&quot;");
491
- return s.replaceAll("\r", "&#13;");
492
- }
493
-
494
- public static String decodeJavaString(String s) {
495
- s = s.replaceAll("&amp;", "&");
496
- s = s.replaceAll("&lt;", "<");
497
- s = s.replaceAll("&gt;", ">");
498
- return s.replaceAll("&#13;", "\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("&amp;")) 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
- }