Gerben Wierda wrote:

I've got a XML file that contains the following snippet

    <TPM:Requires>
      <TPM:Package name="adobeuro"/>
      <TPM:Package name="avantgar"/>
      <TPM:Package name="bookman"/>
      <TPM:Package name="charter"/>
      <TPM:Package name="cmextra"/>
      <TPM:Package name="courier"/>
      <TPM:Package name="euro"/>
      <TPM:Package name="euro-ce"/>
      <TPM:Package name="eurofont"/>
      <TPM:Package name="eurosans"/>
      <TPM:Package name="eurosym"/>
      <TPM:Package name="fpl"/>
      <TPM:Package name="helvetic"/>
      <TPM:Package name="marvosym"/>
      <TPM:Package name="mathpazo"/>
      <TPM:Package name="ncntrsbk"/>
      <TPM:Package name="palatino"/>
      <TPM:Package name="psnfssx"/>
      <TPM:Package name="pxfonts"/>
      <TPM:Package name="rsfs"/>
      <TPM:Package name="symbol"/>
      <TPM:Package name="tex-gyre"/>
      <TPM:Package name="times"/>
      <TPM:Package name="timesnew"/>
      <TPM:Package name="tipa"/>
      <TPM:Package name="txfonts"/>
      <TPM:Package name="utopia"/>
      <TPM:Package name="wasy"/>
      <TPM:Package name="wasysym"/>
      <TPM:Package name="zapfchan"/>
      <TPM:Package name="zapfding"/>
      <TPM:TLCore name="collection-basic"/>
    </TPM:Requires>

Reading this with XML::Simple and Dumping it gives me

  'TPM:Requires' => {
    'TPM:TLCore' => {
      'name' => 'collection-basic'
    },
    'TPM:Package' => {
      'cmextra' => {},
      'wasysym' => {},
      'eurosym' => {},

Basically, when there is only one item, (as with TPM:TLCore above) I get a hash with one item with key 'name' and value whatever is in there, while with multiple entries I get something different, the values have become keys for the hash. Is this not illogical and is there a way to get it in a sipler way? I tried ForceArray => 1, but that gives me arrays instead of hashes. I'd like to get it purely in hashes.

I'm afraid I don't like XML::Simple, because the representation it uses is
both awkward and inaccurate. You should take a look at XML::Twig or XML::LibXML
if you're doing much XML work or if you have anything other than trivial data.

Unfortunately you can't do what you want. Because a hash has unique keys, if a
tag or attribute name in the XML is repeated, this must represented by 
XML::Simple
as a single hash entry with an array as it's value. However by default 
XML::Simple
economises on data nesting by using an array only when the name is repeated and
leaving the value as a simple scalar or hash if it is unique.

In addition, it will do what the documentation calls 'array folding' where if a
value is labelled 'name' 'id' or 'key' then the value is used as the hash key
instead. This is what you have here where 'name' has been thrown away and the
hash keys become the XML attribute values.

To get XML::Simple to store things consistently you must always use

 XMLin($xml, ForceArray => 1, KeyAttr => [])

So that every hash value is an array and all element or attribute names are
mentioned even if they happen to be special words. Your data will then
look like:

'TPM:Requires' => [
 {
   'TPM:TLCore' => [
     {
       'name' => 'collection-basic'
     }
   ],
   'TPM:Package' => [
     {
       'name' => 'adobeuro'
     },
     {
       'name' => 'avantgar'
     },
     {
       'name' => 'bookman'
     },
 :
 :

I hope this helps.

Rob



--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
http://learn.perl.org/


Reply via email to