1
raise "JRuby is required to use the JDOM backend for XmlMini" unless RUBY_PLATFORM =~ /java/
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
13
# = XmlMini JRuby JDOM implementation
15
module XmlMini_JDOM #:nodoc:
18
CONTENT_KEY = '__content__'.freeze
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}
25
NODE_TYPE_NAMES.each { |type| node_type_map[Node.send(type)] = type }
27
# Parse an XML Document string into a simple hash using Java's jdom.
29
# XML Document string to parse
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)
44
# Convert an XML element and merge into the hash
47
# Hash to merge the converted element into.
49
# XML element to merge into hash
50
def merge_element!(hash, element)
51
merge!(hash, element.tag_name, collapse(element))
54
# Actually converts an XML document element into a data structure.
57
# The document element to be collapsed.
59
hash = get_attributes(element)
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
67
merge_texts!(hash, element) unless empty_content?(element)
70
merge_texts!(hash, element)
74
# Merge all the texts of an element into the hash
77
# Hash to add the converted emement to.
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?
85
# must use value to prevent double-escaping
86
merge!(hash, CONTENT_KEY, text_children.join)
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.
96
# Hash to add key/value pair to.
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)
106
hash[key] = [hash[key], value]
108
elsif value.instance_of?(Array)
116
# Converts the attributes array of an XML element into a hash.
117
# Returns an empty Hash if node has no attributes.
120
# XML element to extract attributes from.
121
def get_attributes(element)
123
attributes = element.attributes
124
for i in 0...attributes.length
125
attribute_hash[attributes.item(i).name] = attributes.item(i).value
130
# Determines if a document element has text content
133
# XML element to be checked.
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
146
# Determines if a document element has text content
149
# XML element to be checked.
150
def empty_content?(element)
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
159
text.strip.length == 0