read a xml file

B

Bulhac Mihai

hello, im new in using rexml and a i have a first question: how can a
read this file:
<drive name="c">
<folder name="folder1">
<subfolder name="sub1">
</subfolder>
<subfolder name="sub2">
<file name="file1"></file>
<file name="file2"></file>
</subfolder>
<subfolder name="sub3">
<file name="file1">
</subfolder>

</folder>
<folder name="folder2">
<file name="file1">
</file>
<file name="file2">
</file>
</folder>
</drive>

i want to read all children so that output will be something like that:
drive C
folder folder1
subfolder sub1
subfolder sub2
file file1
file file2
subfoler sub3
folder folder2
file file1
file file2

How can i do that?, Tnx
 
B

Brian Marick

hello, im new in using rexml and a i have a first question: how can a
read this file:
<drive name="c">
<folder name="folder1">
<subfolder name="sub1">
[...]

I'd use xml-simple.

% gem install xml-simple

Then a program like this:

require 'xmlsimple'
require 'pp'
pp XmlSimple.xml_in('xml.xml')

will produce this structure of hashes and arrays:

{"name"=>"c",
"folder"=>
[{"name"=>"folder1",
"subfolder"=>
[{"name"=>"sub1", "content"=>"\n "},
{"name"=>"sub2", "file"=>[{"name"=>"file1"}, {"name"=>"file2"}]},
{"name"=>"sub3", "file"=>[{"name"=>"file1"}]}]},
{"name"=>"folder2",
"file"=>
[{"name"=>"file1", "content"=>"\n "},
{"name"=>"file2", "content"=>"\n "}]}]}

You can customize the printing to suit your taste. There are different
options to xml-simple that let you control the array/hash structure
that gets generated.
 
B

Bulhac Mihai

but i want to read that structure of file; i did try with rexml and i
havent figure it out yet
 
B

Bob Hutchison

Hi,

hello, im new in using rexml and a i have a first question: how can a
read this file:
<drive name="c">
<folder name="folder1">
<subfolder name="sub1">
</subfolder>
<subfolder name="sub2">
<file name="file1"></file>
<file name="file2"></file>
</subfolder>
<subfolder name="sub3">
<file name="file1">
</subfolder>

</folder>
<folder name="folder2">
<file name="file1">
</file>
<file name="file2">
</file>
</folder>
</drive>

i want to read all children so that output will be something like
that:
drive C
folder folder1
subfolder sub1
subfolder sub2
file file1
file file2
subfoler sub3
folder folder2
file file1
file file2

How can i do that?, Tnx

You're going to have to work out which 'parser' you want to use. I
think there are three in REXML: DOM, SAX, and a pull parser.

Choosing the parser to use is a little tricky, and will depend on what
you plan to do with the parsed XML file.

FWIW, I tend to use either my own pull parser or libxml.

With my thing, xampl-pp (a pull parser), installed as a gem, you'd
write this as:

require "xampl-pp"

def format(filename)
xpp = Xampl_PP.new
xpp.input = File.new(filename)

loop do
case xpp.nextEvent
when Xampl_PP::START_ELEMENT
print " " * (xpp.depth - 1)
print xpp.name
xpp.attributeValue.each { | v | print " #{ v }" }
print "\n"
when Xampl_PP::END_DOCUMENT
break
end
end
end

format("./test.xml")

And you'd get exactly the output you wanted.

This is such a simple use of the parser that it is hard to choose
between them.

Cheers,
Bob
 
P

Phrogz

hello, im new in using rexml and a i have a first question: how can a
read this file:
<drive name="c">
<folder name="folder1">
<subfolder name="sub1">
</subfolder>
<subfolder name="sub2">
<file name="file1"></file>
<file name="file2"></file>
</subfolder>
<subfolder name="sub3">
<file name="file1">
</subfolder>

</folder>
<folder name="folder2">
<file name="file1">
</file>
<file name="file2">
</file>
</folder>
</drive>

i want to read all children so that output will be something like that:
drive C
folder folder1
subfolder sub1
subfolder sub2
file file1
file file2
subfoler sub3
folder folder2
file file1
file file2

Note that I had to fix your XML - you were missing a closing tag for
one of your files.

def show_item( rexml_element, level=0 )
print " "*level
puts "#{rexml_element.name} #{rexml_element.attributes['name']}"
rexml_element.elements.each{ |el|
show_item( el, level+1 )
}
end

require 'rexml/document'
doc = REXML::Document.new( DATA.read )

show_item( doc.root )

__END__
<drive name="c">
<folder name="folder1">
<subfolder name="sub1">
</subfolder>
<subfolder name="sub2">
<file name="file1"></file>
<file name="file2"></file>
</subfolder>
<subfolder name="sub3">
<file name="file1" />
</subfolder>
</folder>
<folder name="folder2">
<file name="file1">
</file>
<file name="file2">
</file>
</folder>
</drive>
 
P

Phrogz

hello, im new in using rexml and a i have a first question: how can a
read this file:
<drive name="c">
<folder name="folder1">
<subfolder name="sub1">
</subfolder>
<subfolder name="sub2">
<file name="file1"></file>
<file name="file2"></file>
</subfolder>
<subfolder name="sub3">
<file name="file1">
</subfolder>

</folder>
<folder name="folder2">
<file name="file1">
</file>
<file name="file2">
</file>
</folder>
</drive>

i want to read all children so that output will be something like that:
drive C
folder folder1
subfolder sub1
subfolder sub2
file file1
file file2
subfoler sub3
folder folder2
file file1
file file2

Note that if your XML is properly indented already, you don't even
need an XML parser for this particular task:

source = DATA.read
# remove explicit closing elements
source.gsub! %r{</.+?>}, ''

# remove empty lines
source.gsub! %r{^[ \t]+\n}, ''

# convert tags to desired output
source.gsub! /<(\w+)\s+name="(.+?)".+/, '\1 \2'

puts source
__END__
<drive name="c">
<folder name="folder1">
<subfolder name="sub1">
</subfolder>
<subfolder name="sub2">
<file name="file1"></file>
<file name="file2"></file>
</subfolder>
<subfolder name="sub3">
<file name="file1" />
</subfolder></folder>
<folder name="folder2">
<file name="file1">
</file>
<file name="file2">
</file>
</folder>
</drive>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,207
Messages
2,571,078
Members
47,681
Latest member
hanrywillsonnn

Latest Threads

Top