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

I am looking a solution for merging 2 different XML files without using XML::Parser modules.

Both files are in same structure. (Not even requiring DTD)

<A id="a1"> <B id="b1"> <C id="c1"> <D>d1</D> <D>d2</D> </C> <C id="c2"> <D>d3</D> </C> </B> </A>
Just note that ID value a1,b1 etc.. are just the place holders.
I haven't put the actual tags.
and this is not homework.

Replies are listed 'Best First'.
(jcwren) Re: Merging XML
by jcwren (Prior) on Nov 27, 2001 at 22:15 UTC

    Without having written any code to verify this, this seems like a most excellent use of Hash::Merge and XML::Simple.

    In theory, it should be something as easy as this:

    use XML::Simple; use Hash::Merge; my %config1 = %{XMLin ('file1')}; my %config2 = %{XMLin ('file2')}; my %newhash; Hash::Merge::set_behavior ('RIGHT_PRECEDENT'); *newhash = merge (\%config1, \%config2); XMLout (\%newhash, outputfile => "newfile", xmldecl => 1, rootname => +'config');

    While this code is theoretical, I use a variant of it for a similiar purpose, and it works flawlessly. I don't know if what you want to do can be done reliably, without using some XML module or another.


    e-mail jcwren

      Making use of XML::Simple requires XML::Parser which I would like to avoid due to problems installing expat.
      Hi Chris, This works fine,
      It works great, except it duplicates instead of overwriting the things.
      ex.. If I am trying to merge same 2 files, it makes bigger file which is double the size of single file approximately

        I think you probably need to post the two source XML files to your scratchpad or as a follow-up to the original article. Hash::Merge has a couple of options, and a different one may need to be selected. It does merge correctly, assuming that your input XML structure is as you say it is. But without a real data set, it's impossible to tell for sure.


        e-mail jcwren

Re: Merging XML
by mirod (Canon) on Nov 27, 2001 at 22:21 UTC

    You only show one file! Could you give examples of the 2 files and how you would like to merge them?

    If you don't want to use modules based on XML::Parser (would you care to explain why BTW?) you can use XML::SAX::PurePerl or XML::libXML or maybe even XML::Parser::Lite. In any case please, for your own sake, use a parser, not regular expressions!

      As I said, the structure of the other file is same..
      Here is another file anyway
      <A id="a1"> <B id="b2"> <C id="c1"> <D>d1</D> <D>d2</D> </C> <C id="c2"> <D>d3</D> </C> </B> <B id="b3"> <C id="c1"> <D>d1</D> <D>d2</D> </C> <C id="c2"> <D>d3</D> </C> </B> </A> <A id="a2"> <B id="b4"> <C id="c1"> <D>d1</D> <D>d2</D> </C> <C id="c2"> <D>d3</D> </C> </B> <B id="b5"> <C id="c1"> <D>d1</D> <D>d2</D> </C> <C id="c2"> <D>d3</D> </C> </B> </A>
      Where I would look for libxml? on my system..
      I have hard time installing XML::Parser on my system mainly due to expat.
      I would appriciate, if someone can put steps to install XML::Parser locally with 'exact' example.
      Thanks, Artist

        Now we have 2 files, but I still have no idea what the resulting "merged" file should look like. It could be:

        <Z><A id="a1">...</A><A id="a2">...</A></Z>

        which would be quite easy to do, you don't even need Perl for this, but it could also be a file where only D elements are added according to conditions on various tags/attributes...

        What system are you trying to install XML::Parser on? Versions up to 2.29 include expat, so all you need is a C compiler, gcc works fine, to install the module. The only problem you can find is that it can collide with the static install of expat done by Apache. So version 2.30 comes without expat, which you have to install (you can find expat on sourceforge here).