# Read a xml file

**URL:** <https://www.ruby-forum.com/t/read-a-xml-file/121073>\
**Category:** Ruby\
**Created:** [November 23, 2007, 2:14pm UTC](https://www.ruby-forum.com/t/read-a-xml-file/121073 "2007-11-23T14:14:44Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![mihai](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/35a633/32.png) [@mihai](https://www.ruby-forum.com/u/mihai)\
**Post date:** [November 23, 2007, 2:14pm UTC](https://www.ruby-forum.com/t/read-a-xml-file/121073/1 "2007-11-23T14:14:44Z")

</div>

hello, im new in using rexml and a i have a first question: how can a  
read this file:

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

---

<div class="post-metadata">

**Author:** ![mihai](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/35a633/32.png) [@mihai](https://www.ruby-forum.com/u/mihai)\
**Post date:** [November 23, 2007, 2:34pm UTC](https://www.ruby-forum.com/t/read-a-xml-file/121073/2 "2007-11-23T14:34:39Z")

</div>

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

> hello, im new in using rexml and a i have a first question: how can a  
> read this file:  
>   
>   
>   
> […]

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 M., independent consultant  
Mostly on agile methods with a testing slant  
[www.exampler.com](http://www.exampler.com), [Exploration Through Example](http://www.exampler.com/blog), [twitter.com/marick](http://twitter.com/marick)

---

<div class="post-metadata">

**Author:** ![mihai](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/35a633/32.png) [@mihai](https://www.ruby-forum.com/u/mihai)\
**Post date:** [November 23, 2007, 2:38pm UTC](https://www.ruby-forum.com/t/read-a-xml-file/121073/3 "2007-11-23T14:38:42Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![mihai](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/35a633/32.png) [@mihai](https://www.ruby-forum.com/u/mihai)\
**Post date:** [November 23, 2007, 3:39pm UTC](https://www.ruby-forum.com/t/read-a-xml-file/121073/4 "2007-11-23T15:39:42Z")

</div>

Hi,

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

> 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-forum.com/](http://www.ruby-forum.com/).

* * *

Bob H. – tumblelog at  
[http://www.recursive.ca/so/](http://www.recursive.ca/so/)  
Recursive Design Inc. – weblog at  
[http://www.recursive.ca/hutch](http://www.recursive.ca/hutch)  
[http://www.recursive.ca/](http://www.recursive.ca/) – works on  
[http://www.raconteur.info/cms-for-static-content/home/](http://www.raconteur.info/cms-for-static-content/home/)

---

<div class="post-metadata">

**Author:** ![mihai](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/35a633/32.png) [@mihai](https://www.ruby-forum.com/u/mihai)\
**Post date:** [November 23, 2007, 7:16pm UTC](https://www.ruby-forum.com/t/read-a-xml-file/121073/5 "2007-11-23T19:16:14Z")

</div>

On Nov 23, 6:14 am, Bulhac M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> <subfolder name="sub3">
> 
> ```
> 
> 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**

---

<div class="post-metadata">

**Author:** ![mihai](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/35a633/32.png) [@mihai](https://www.ruby-forum.com/u/mihai)\
**Post date:** [November 23, 2007, 7:25pm UTC](https://www.ruby-forum.com/t/read-a-xml-file/121073/6 "2007-11-23T19:25:36Z")

</div>

On Nov 23, 6:14 am, Bulhac M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> ```
> <subfolder name="sub3">
> 
> ```
> 
> 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**
