Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Parsing XML data and injecting it into new file

by hosselausso (Initiate)
on Sep 05, 2021 at 15:46 UTC ( [id://11136468]=perlquestion: print w/replies, xml ) Need Help??

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

I have several xml files from where I want to read data and put it together in a single xml file. The origin files look all like this like this:
<testsuites> <testsuite name="test_suite_name" ...> <testcase name="test1" .../> <testcase name="test2" .../> <testsuite name="some_name" ...> </testsuites>
So, basically a single node "testsuite" which contains several "testcases" in each file. So I basically want to extract the "testsuite" node from each file and put it into a new file. I also would like to modify the attribute "name" of each testsuite. So far I have:
my $dom = XML::LibXML::Document->new('1.0', 'utf-8'); my $xml1 = XML::LibXML->load_xml(location => 'file1.xml'); my $xml2 = XML::LibXML->load_xml(location => 'file2.xml'); my $root = $dom->createElement('testsuites'); $dom->setDocumentElement($root); my $testsuite1 = $xml1->findnodes('//testsuite'); my $testsuite2 = $xml2->findnodes('//testsuite'); my $child = $dom->createElement($testsuite1); # <-- fails $root->appendChild($child); open XML, ">result.xml"; print XML $dom->toString(); close XML;
$testsuite1 is a XML::LibXML::NodeList object type. Is there a way to use that object to inject it in some way to $doc?

Replies are listed 'Best First'.
Re: Parsing XML data and injecting it into new file
by haukex (Archbishop) on Sep 05, 2021 at 15:59 UTC

    Note the input data you've shown isn't valid XML, and you haven't shown the expected output, so I have to guess at what you want. See How do I post a question effectively? and Short, Self-Contained, Correct Example.

    As documented, ->findnodes in scalar context returns an XML::LibXML::NodeList object, which you can't pass to ->createElement. Here's one approach:

    use warnings; use strict; use XML::LibXML; my @files = ("file1.xml", "file2.xml", "file3.xml"); my $outfile = "result.xml"; my $newdom = XML::LibXML::Document->new('1.0', 'UTF-8'); my $root = $newdom->createElement('testsuites'); $newdom->setDocumentElement($root); for my $file (@files) { my $dom = XML::LibXML->load_xml(location => $file); for my $node ( $dom->findnodes('//testsuite') ) { $node->{name} =~ s/test_suite_name_/tsname_/; $root->appendChild($node); } } $newdom->toFile($outfile, 1);

    With input files that look like this:

    <?xml version="1.0" encoding="UTF-8"?> <testsuites> <testsuite name="test_suite_name_one"> <testcase name="test1" /> <testcase name="test2" /> </testsuite> </testsuites>

    It produces output like this:

    <?xml version="1.0" encoding="UTF-8"?> <testsuites> <testsuite name="tsname_one"> <testcase name="test1"/> <testcase name="test2"/> </testsuite> <testsuite name="tsname_two"> <testcase name="test3"/> <testcase name="test4"/> </testsuite> <testsuite name="tsname_three"> <testcase name="test5"/> <testcase name="test6"/> </testsuite> </testsuites>
      This is exactly what I was asking. Thank you very much and sorry for missing the expected outcome.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11136468]
Approved by haukex
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others learning in the Monastery: (5)
As of 2024-03-28 20:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found