Changesets can be listed by changeset number.
The Git repository is here.
- Revision:
- 373
- Log:
Initial import of Radiant 0.9.1, which is now packaged as a gem. This is an
import of the tagged 0.9.1 source checked out from GitHub, which isn't quite
the same as the gem distribution - but it doesn't seem to be available in an
archived form and the installed gem already has modifications, so this is
the closest I can get.
- Author:
- rool
- Date:
- Mon Mar 21 13:40:05 +0000 2011
- Size:
- 4794 Bytes
1 | raise "JRuby is required to use the JDOM backend for XmlMini" unless RUBY_PLATFORM =~ /java/ |
2 | |
3 | require 'jruby' |
4 | include Java |
5 | |
6 | import javax.xml.parsers.DocumentBuilder unless defined? DocumentBuilder |
7 | import javax.xml.parsers.DocumentBuilderFactory unless defined? DocumentBuilderFactory |
8 | import java.io.StringReader unless defined? StringReader |
9 | import org.xml.sax.InputSource unless defined? InputSource |
10 | import org.xml.sax.Attributes unless defined? Attributes |
11 | import org.w3c.dom.Node unless defined? Node |
12 | |
13 | # = XmlMini JRuby JDOM implementation |
14 | module ActiveSupport |
15 | module XmlMini_JDOM #:nodoc: |
16 | extend self |
17 | |
18 | CONTENT_KEY = '__content__'.freeze |
19 | |
20 | NODE_TYPE_NAMES = %w{ATTRIBUTE_NODE CDATA_SECTION_NODE COMMENT_NODE DOCUMENT_FRAGMENT_NODE |
21 | DOCUMENT_NODE DOCUMENT_TYPE_NODE ELEMENT_NODE ENTITY_NODE ENTITY_REFERENCE_NODE NOTATION_NODE |
22 | PROCESSING_INSTRUCTION_NODE TEXT_NODE} |
23 | |
24 | node_type_map = {} |
25 | NODE_TYPE_NAMES.each { |type| node_type_map[Node.send(type)] = type } |
26 | |
27 | # Parse an XML Document string into a simple hash using Java's jdom. |
28 | # string:: |
29 | # XML Document string to parse |
30 | def parse(string) |
31 | if string.blank? |
32 | {} |
33 | else |
34 | @dbf = DocumentBuilderFactory.new_instance |
35 | xml_string_reader = StringReader.new(string) |
36 | xml_input_source = InputSource.new(xml_string_reader) |
37 | doc = @dbf.new_document_builder.parse(xml_input_source) |
38 | merge_element!({}, doc.document_element) |
39 | end |
40 | end |
41 | |
42 | private |
43 | |
44 | # Convert an XML element and merge into the hash |
45 | # |
46 | # hash:: |
47 | # Hash to merge the converted element into. |
48 | # element:: |
49 | # XML element to merge into hash |
50 | def merge_element!(hash, element) |
51 | merge!(hash, element.tag_name, collapse(element)) |
52 | end |
53 | |
54 | # Actually converts an XML document element into a data structure. |
55 | # |
56 | # element:: |
57 | # The document element to be collapsed. |
58 | def collapse(element) |
59 | hash = get_attributes(element) |
60 | |
61 | child_nodes = element.child_nodes |
62 | if child_nodes.length > 0 |
63 | for i in 0...child_nodes.length |
64 | child = child_nodes.item(i) |
65 | merge_element!(hash, child) unless child.node_type == Node.TEXT_NODE |
66 | end |
67 | merge_texts!(hash, element) unless empty_content?(element) |
68 | hash |
69 | else |
70 | merge_texts!(hash, element) |
71 | end |
72 | end |
73 | |
74 | # Merge all the texts of an element into the hash |
75 | # |
76 | # hash:: |
77 | # Hash to add the converted emement to. |
78 | # element:: |
79 | # XML element whose texts are to me merged into the hash |
80 | def merge_texts!(hash, element) |
81 | text_children = texts(element) |
82 | if text_children.join.empty? |
83 | hash |
84 | else |
85 | # must use value to prevent double-escaping |
86 | merge!(hash, CONTENT_KEY, text_children.join) |
87 | end |
88 | end |
89 | |
90 | # Adds a new key/value pair to an existing Hash. If the key to be added |
91 | # already exists and the existing value associated with key is not |
92 | # an Array, it will be wrapped in an Array. Then the new value is |
93 | # appended to that Array. |
94 | # |
95 | # hash:: |
96 | # Hash to add key/value pair to. |
97 | # key:: |
98 | # Key to be added. |
99 | # value:: |
100 | # Value to be associated with key. |
101 | def merge!(hash, key, value) |
102 | if hash.has_key?(key) |
103 | if hash[key].instance_of?(Array) |
104 | hash[key] << value |
105 | else |
106 | hash[key] = [hash[key], value] |
107 | end |
108 | elsif value.instance_of?(Array) |
109 | hash[key] = [value] |
110 | else |
111 | hash[key] = value |
112 | end |
113 | hash |
114 | end |
115 | |
116 | # Converts the attributes array of an XML element into a hash. |
117 | # Returns an empty Hash if node has no attributes. |
118 | # |
119 | # element:: |
120 | # XML element to extract attributes from. |
121 | def get_attributes(element) |
122 | attribute_hash = {} |
123 | attributes = element.attributes |
124 | for i in 0...attributes.length |
125 | attribute_hash[attributes.item(i).name] = attributes.item(i).value |
126 | end |
127 | attribute_hash |
128 | end |
129 | |
130 | # Determines if a document element has text content |
131 | # |
132 | # element:: |
133 | # XML element to be checked. |
134 | def texts(element) |
135 | texts = [] |
136 | child_nodes = element.child_nodes |
137 | for i in 0...child_nodes.length |
138 | item = child_nodes.item(i) |
139 | if item.node_type == Node.TEXT_NODE |
140 | texts << item.get_data |
141 | end |
142 | end |
143 | texts |
144 | end |
145 | |
146 | # Determines if a document element has text content |
147 | # |
148 | # element:: |
149 | # XML element to be checked. |
150 | def empty_content?(element) |
151 | text = '' |
152 | child_nodes = element.child_nodes |
153 | for i in 0...child_nodes.length |
154 | item = child_nodes.item(i) |
155 | if item.node_type == Node.TEXT_NODE |
156 | text << item.get_data.strip |
157 | end |
158 | end |
159 | text.strip.length == 0 |
160 | end |
161 | end |
162 | end |