I tend to fall back on either XML::LibXML or XML::Twig, depending on exactly what I am doing, and how enormous the XML file is. Twig is good for processing a great big file incrementally – it is a parser that can call your code at strategic points, but which does not transform the XML file structure into an in-memory structure. XML::LibXML’s advantage is that under the hood it leverages libxml2, which is an industry-standard binary that I think is the actual source of most of the XML files that you are likely to receive. So, if compatibility with a distant planet is an important consideration (and if you want to pre-flight your files to be sure that they will be acceptable), this is a good way to go. This binary library implements everything associated with XML processing, in an industry-standard way.
“Handwritten” XML is also seen a lot, especially when you know that it will not change or when one in-house app is talking to another, but there was a recent thread here where someone seems to have gotten bitten by “character sets” with such a program. (Switch from Latin1 to UTF-8.) XML read/writers will categorically take care of all that, if used correctly.
The third most-common contender, XML::Simple, is a little too simple for my taste. I have experienced various problems with both reading and writing if the use-case gets anywhere close to being an edge-case. (However, it is simple, and sometimes functional XML requirements are simple, too.)