Howdy Monks,
not that I'd want to dump my XML::Rules, but there is another idea that might help a bit using XML::Simple. One of the things that makes using the XML::Simple produced datastructure harder is inconsistency. Unless you specify otherwise you may once find the key "foo" pointing to a single value or single hash and other time to an array of values or hashes. Based on whether it was encountered once or more times in the parent node. So you want to use ForceArray to make sure it's always array ... but would you want to use it for all tags? Including those that may only appear once in the parent node according to the DTD or schema? Probably not. So why not have a tool that extracts the list of tags that may be repeated from the DTD/Schema?

Another common inconsistency is the handling of tag content. If the tag has no attributes you get tagname => 'value', if it does you get tagname => {attr=> 1, content => 'value'}. So if you have a tag that sometimes does have attributes and sometimes does not you have to test whether you've got a hashref or a plain scalar. Or you can turn on ForceContent and get a hash for all. Including the ones that may never have any attributes or child nodes.

So I wonder whether there'd be any interest in 1)extending XML::Simple so that ForceContent accepts a list of tags just like ForceArray does and 2) either extend XML::Simple or provide a tool to generate the lists of tags that can be repeated for ForceArray and those that may have both attributes and content for ForceContent.

Replies are listed 'Best First'.
Re: XML::Simple, ForceArray, ForceContent and DTD/Schema
by ikegami (Patriarch) on Nov 17, 2006 at 21:17 UTC

    The highly polymorphic nature of XML::Simple is definitely makes XML::Simple not so. ForceArray and ForceContent are required to produce useable returns. I see the ability to fine tune ForceArray and ForceContent as useful.

    Change (1) is a simple and it has no compatibility issues, so why don't you write and submit a patch?

    Change (2) could easily be implemented by a seperate module that provides an interface to XML::Simple. That might be the way the better way to go.

      Thanks. I will do (1), I don't think the (2) should actually be a module. It's IMHO rather a task for a script, than a module. Something you run once when developing the script or module for that particular XML format. Though I'm afraid I can only write the one for DTDs, unless I'm forced to learn Schemas which I do hope I never will.

        If I was going to do #2 for XML Schema I'd start by adding schema data to the stream produced by XML::Validator::Schema. Then I'd create a handler which uses this sweetened data to create sensible defaults for ForceArray and ForceContent in XML::Simple.

        Give XML Schema a try some time. I've found if you stay away from the nuttier features it can be a pretty reasonable, if verbose, alternative to DTDs (which I loathe). To help you keep it simple (heh) XML::Validator::Schema only supports a small subset of the standard anyway.

        -sam

Re: XML::Simple, ForceArray, ForceContent and DTD/Schema
by GrandFather (Saint) on Nov 17, 2006 at 21:15 UTC

    Judging by the number of SoPW questions about XML::Simple it is already complicated enough. Perhaps what is needed is an XML::AlmostSimple or XML::Simple::TrickyBits?

    Actually, rather than adding bits and bobs to XML::Simple, perhaps it is more appropriate to use XML::Twig's Simple mode or even its not so simple mode?


    DWIM is Perl's answer to Gödel
Re: XML::Simple, ForceArray, ForceContent and DTD/Schema
by wazoox (Prior) on Nov 20, 2006 at 17:07 UTC
    Once upon a time I started a project using XML::Simple, but it went so complicated to keep output consistent that I ended using XML::LibXML, and all is fine and great ever since.
    XML::Simple is deceptive, unless you stick to really very trivial XML usage.
Re: XML::Simple, ForceArray, ForceContent and DTD/Schema
by Penfold (Novice) on Nov 20, 2006 at 14:28 UTC
    I'd love it - it's one of the banes of my life, using XML::Simple :) To be fair, a reasonable answer to this is 'well, use XML::<Less Simple>, then' :)