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

File.xml
<contacts> <entry> <name>File1</name> <street>123 Platypus Lane</street> <city>Burgopolis</city> <state>FL</state> <zip>12345</zip> </entry> <entry> <name>File2</name> <street>123 Platypus Lane</street> <city>Burgopolis</city> <state>FL</state> <zip>678</zip> </entry> <entry> <name>File3</name> <street>123 Platypus Lane</street> <city>Burgopolis</city> <state>FL</state> <zip>910</zip> </entry> </contacts>
This is one XML file. How to break this into 3 files which contains filename as <name> tag.
#!/usr/bin/perl use XML::XPath; my $file = 'file.xml'; my $xp = XML::XPath->new(filename=>$file); my $nodeset = $xp->find('//name'); my @names; # Where we'll put our results if (my @nodelist = $nodeset->get_nodelist) { @names = map($_->string_value, @nodelist); # Now sort and prepare for output @names = sort(@names); local $" = "\n"; print "I found these names:\n@names\n"; }
File1.xml, File2.xml,File3.xml will be created.

Replies are listed 'Best First'.
Re: XML file to split
by mirod (Canon) on Oct 09, 2009 at 16:22 UTC

    Using the xml_split and xml_grep that come with XML::Twig, you can do this in one (long!) line:

    xml_split -l 1 tsplit.xml \ && perl -e'my @src= glob( "tsplit-*.xml"); \ foreach my $target (`xml_grep -t name tsplit-*.xml`) \ { chomp $target; \ my $src= shift @src; \ warn "rename $src, $target.xml\n"; \ rename $src, "$target.xml"; }'

    Replace tsplit.xml by your file name of course.

Re: XML file to split
by ikegami (Patriarch) on Oct 09, 2009 at 16:15 UTC
    Do a search. This some up often. You even used the same terms as the previous posters (xml, split)
Re: XML file to split
by NetWallah (Canon) on Oct 09, 2009 at 17:20 UTC
    Perhaps something along the lines of this:
    #!/usr/bin/perl use XML::XPath; my $xp = XML::XPath->new(xml=> join '',<DATA>); my @names; # Where we'll put our results for my $entry ( $xp->findnodes('//entry') ) { my $filename = $entry->findvalue("./name"); my $content = $entry->toString; print "---File $filename would contain---\n $content\n"; push @names,$filename; } # Now sort and prepare for output @names = sort(@names); print "I found these names:\n@names\n"; __DATA__ <contacts> <entry> <name>File1</name> <street>123 Platypus Lane</street> <city>Burgopolis</city> <state>FL</state> <zip>12345</zip> </entry> <entry> <name>File2</name> <street>123 Platypus Lane</street> <city>Burgopolis</city> <state>FL</state> <zip>678</zip> </entry> <entry> <name>File3</name> <street>123 Platypus Lane</street> <city>Burgopolis</city> <state>FL</state> <zip>910</zip> </entry> </contacts>
    Output:

         Potentia vobiscum ! (Si hoc legere scis nimium eruditionis habes)

      #!/usr/bin/perl use XML::XPath; my $xp = XML::XPath->new(xml=> join '',<DATA>); my @names; # Where we'll put our results for my $entry ( $xp->findnodes('//entry') ) { my $filename = $entry->findvalue("./name"); my $content = $entry->toString; $content=~ s/[\cA-\cZ]//g; $content=~ s/\^[A-Z]//g; print "---File $filename would contain---\n $content\n"; } __DATA__ <contacts> <entry>^M <name>File1</name> <street>123 Platypus Lane</street> <city>Burgopolis</city> <state></state> <zip>12345</zip> </entry> <entry> <name>File2</name> <street>123 Platypus Lane</street> <city></city> <state>FL</state> <zip>678</zip> </entry> <entry> <name>File3</name> <street></street> <city>Burgopolis</city> <state>FL</state> <zip>910 </zip> </entry> </contacts>
      How to format the XML file and strip out the empty tags. The tags are not printed in the separate lines.
        How to strip out the empty tags and format the XML file. Please tell me
Re: XML file to split
by llancet (Friar) on Oct 10, 2009 at 07:37 UTC
    See XML::DOM, it should be helpful