[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

read a xml file

Bu Mihai

11/23/2007 1:15:00 PM

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
--
Posted via http://www.ruby-....

5 Answers

Brian Marick

11/23/2007 1:34:00 PM

0


On Nov 23, 2007, at 7:14 AM, Bulhac Mihai wrote:

> 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.

-----
Brian Marick, independent consultant
Mostly on agile methods with a testing slant
www.exampler.com, www.exampler.com/blog, twitter.com/marick

-----
Brian Marick, independent consultant
Mostly on agile methods with a testing slant
www.exampler.com, www.exampler.com/blog, twitter.com/marick


Bu Mihai

11/23/2007 1:39:00 PM

0

but i want to read that structure of file; i did try with rexml and i
havent figure it out yet
--
Posted via http://www.ruby-....

Bob Hutchison

11/23/2007 2:38:00 PM

0

Hi,

On 23-Nov-07, at 8:14 AM, Bulhac Mihai wrote:

> 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


>
> --
> Posted via http://www.ruby-....
>

----
Bob Hutchison -- tumblelog at http://www.recurs...
Recursive Design Inc. -- weblog at http://www.recursiv...
http://www.rec... -- works on http://www.raconteur.info/cms-for-static-con...



Phrogz

11/23/2007 6:10:00 PM

0

On Nov 23, 6:14 am, Bulhac Mihai <mihai.bul...@yahoo.com> wrote:
> 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>

Phrogz

11/23/2007 6:23:00 PM

0

On Nov 23, 6:14 am, Bulhac Mihai <mihai.bul...@yahoo.com> wrote:
> 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>