Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??
As mentioned in one of my recent nodes, WxPerl woes -- putting a Tree into a ScrolledWindow, I am writing my final year project using wxPerl. I have been struggling, but thanks to help from Jouke and the wxPerl mailing list, I've been making progress. Anyway, the program is an MP3 organiser--it stores information on various "volumes" (parts of a user's collection - a volume can be either a drive on fixed media or removable media, and possibly remote locations). These volumes are stored as XML files, using a DTD that I have created. A sample document is presented below:

<?xml version="1.0" encoding="utf-8"?> <volume device="cdrom" date="2002-02-10" start="d:/" name="Test"> <directory name="Singles"> <file encoding="CBR" stereo="jointstereo" bitrate="192" format="MP +3" name="Metallica - Wherever I May Roam.mp3" size="500000"> <artist>Metallica</artist> <title>Wherever I May Roam</title> <duration>230</duration> <album>Metallica</album> <reldate>1991</reldate> <label>Elektra</label> </file> <file encoding="CBR" stereo="jointstereo" bitrate="192" format="MP +3" name="Linkin Park - In the End.mp3" size="5000000"> <artist>Linkin Park</artist> <title>In The End</title> <duration>250</duration> <album>Hybrid Theory</album> <reldate>1999</reldate> <label>Sony</label> </file> <cover file="front.jpg" format="JPEG" width="100" height="200" side="front"/> <cover file="back.jpg" format="JPEG" width="100" height="200" side="back"/> </directory> <directory name="Cheesy Tunes"> <directory name="Super Cheesy Tunes"> <file encoding="CBR" bitrate="192" name="Village People - YMCA.mp3 +"> </file> </directory> </directory> </volume>
A few points: directories can contain unlimited directory and file tags. The artist, title etc. tags can exist only inside 'file' tags.

The final application is intended to look something like this screenshot, i.e. a tree with an entry for each volume and each of its subdirectories (recursively). Note in the screenshot that 'Test' and 'Test' are 2 different volumes. When the user clicks on a particular directory, the contents of that directory (whether they are files or more directories) should be displayed in the right-hand pane.

I have implemented this in a rather 'hacked' and far from perfect fashion. In the constructor for my frame, I call a function in package main which sets global variables (using our) in main to store a reference to the tree object and to the current "ID" (the ID is used to denote where an entry into the tree should be inserted), i.e.

our (@stack, @directory, %file); our ($treeId, $treeRef, $treeRoot, $lastXMLElement); sub describeTreeObject { ($treeRef, $treeId) = @_; $treeRoot = $treeId; }
I can create the actual tree (with volumes and directories) fine. I used a 'stack' approach, keeping the ID of the next entry to be inserted at the top of the stack, and popping it off whenever an end tag for 'directory' is encountered. (The stack is then cleared before starting another volume.)

The problem is storing data on the files and linking this to what volume they are on, and what the 'properties' of the volume are. The hack I have used is as follows:

  1. When a 'file' tag is encountered, its attributes are stored in a global hash, %file.
  2. When any character data is encountered, it is inserted into the %file hash using the value of the last XML tag started as they key.
  3. When the end of a 'file' tag is encountered, a 'narrower scoped' version of the %file hash is created using my, and a reference to it is pushed onto a public array, @directory.
  4. When the end of a 'directory' tag is encountered, the @directory array is copied and a scalar reference to it is set as the tree item's data. (So, in other words, the data for the 'Singles' entry in the screenshot would contain an array reference to an array of hash refs, each contain element of which would contain a hash describing the file.)
  5. When the user 'activates' an item in the tree, that item's data is inserted into the wxListCtrl opposite.
The problems with this approach are:
  • Data on volumes is not stored anywhere. (Should be easily accessible.)
  • Directories and files are not distinguished between (in the final version, I hope to have a different icon for directories and files).
  • Directories are not included in the list, i.e. if I have a directory called 'Foo' that includes directories 'Bar' and 'Baz' and also 3 files, the 3 files will be displayed, but directories 'Bar' and 'Baz' will not be. The desired behaviour is that when a directory is selected in the tree, its subdirectories will be displayed in the wxListCtrl, and the same for volumes.
Anyone got any suggestions for how to go about doing this? (I am using XML::Parser by the way).

Also, if you've read this far, thanks--I know this is a long posting, but I felt it was important to explain the situation as clearly as possible and include all relevant information.

In reply to XML with wxPerl by SuperCruncher

Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":

  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?

    What's my password?
    Create A New User
    and the fire pops...

    How do I use this? | Other CB clients
    Other Users?
    Others examining the Monastery: (7)
    As of 2018-04-25 07:09 GMT
    Find Nodes?
      Voting Booth?