isync has asked for the wisdom of the Perl Monks concerning the following question:

I am handling a number of different XML documents which follow alternating namespace declaration policies. When parsing them with XML::Simple I get structures like this:
$VAR1 = { 'A:tree' => [ { 'A:twig' => [ { 'B:person' => [ { 'B:name' => [ 'J +im', 'J +ohn' ] } ] } ] } ], 'xmlns:B' => 'http://people.example.com/sitting-on-trees-ns' +, 'xmlns:A' => 'Plants:' };
and this
$VAR1 = { 'A:tree' => [ { 'A:twig' => [ { 'person' => [ { 'xmlns' => 'http://p +eople.example.com/sitting-on-trees-ns', 'content' => 'Jim' } ] } ] }, ], 'xmlns:A' => 'Plants:' };
As you can see, the first type of XML documents only declares namespaces in the "root-node". The second type of XML documents declares namespaces in a kind of mixed mode: some ns are declared in the "root-node" while others are opened along the way as attribs to keys or values, somewhere down in the nested structure.

Monks,
is there a clever module which does the work of "collecting" the namespaces for me? So that it transforms the second data structure into one resembling the first, moving the ns from the twigs into the root while prepending prefixes pointing to the moved ns automatically?
That would be great!

Replies are listed 'Best First'.
Re: How to unify XML namespace notation
by ikegami (Patriarch) on Aug 24, 2010 at 18:40 UTC
    XML::Simple is particularly bad with namespaces, but using the NSExpand=>1 option is documented to provide uniform results. Note the caveat.
      I've already looked into the NSExpand option but it didn't produce the clean results I was hoping for. But might be a good starting point, now, on second sight.

      Still, I am open to walking away from XML::Simple, any hints then?

      Update:
      After playing around with the NSExpand on in and out, I think with a bit of work I can get 90% of what I initially needed. Thanks ikegami!
      Anyone else who has an idea on the "namespace collection" problem, please comment!

        ->{"{$nsA}Foo"} is not much longer than ->{"A:Foo"} and doesn't incorrectly rely on a specific value for the prefix. I don't see how this is a "starting point" and not a final answer.

Re: How to unify XML namespace notation
by Jenda (Abbot) on Aug 24, 2010 at 20:40 UTC

    Have a look at XML::Rules. If you specify the expected namespaces and their expected prefixes, the module will "normalize" the prefixes and then let you produce a datastructure more or less (as needed) like the one produced by XML::Simple.

    Jenda
    Enoch was right!
    Enjoy the last years of Rome.