Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combine Many XML Files

Tags:

merge

xml

xslt

What language can I use to combine multiple XML files. Multiple as 10+ files.

PHP, java, or what?

I tried to use XSLT but I do not know if I need a 'processor' such as Saxon.

The docs were to confusing as I did not know where to start.

All in all, I need someone to point me in the right direction.

Someone please help. I've been trying to figure this out for days

<xml version="1.0">
<products>
<price>Price List Here</price>
<model>Model Number Here</model>
</product>
like image 441
Ryan Avatar asked Jan 20 '23 19:01

Ryan


2 Answers

This can be done easily in pure XSLT:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:param name="pdoc1Url" select="'doc1.xml'"/>
 <xsl:param name="pdoc2Url" select="'doc2.xml'"/>

 <xsl:template match="/">
  <documents>
    <xsl:copy-of select="document($pdoc1Url)"/>
    <xsl:copy-of select="document($pdoc2Url)"/>
  </documents>
 </xsl:template>
</xsl:stylesheet>

The code above deals with two XML documents, but can be extended to deal with any, known in advance number of XML documents.

Explanation:

  1. Passing the URLs for the XML documents as global/external parameters to the transformation.

  2. Use of the standard XSLT function document().

like image 52
Dimitre Novatchev Avatar answered Jan 30 '23 21:01

Dimitre Novatchev


You can use any language that allows you to manipulate xml directly. I suggest finding something with DOM rather than SAX. If you use SAX you have to basically traverse the xml yourself - a pita in my experience. DOM allows you to act on the xml in a more OOP manner.

Something that springs immediately to mind would be a wrapper xml around your xml "documents".

So something like:

<documents>
   <document>
      <!-- Your xml here -->
   </document>
   <document>
      <!-- Your xml here -->
   </document>
   <document>
      <!-- Your xml here -->
   </document>
</documents>

The pseudo code would be: Create a document root. Add an element called documents, use that as the root. Iterate each of your xml files. For each file create a new element called document. Add that element to the parent. Load the xml from the file. Import that node into the outer document. Append the imported node into the document elements child collection.

EDIT As promised here is the updated code that was tested and I know works:

<?php

    // Replace the strings below with the actual filenames, add or decrease as fit
    $filenames = array(0 => "test.xml", 1 => "test2.xml", 2 => "test3.xml" );

    $docList = new DOMDocument();

    $root = $docList->createElement('documents');
    $docList->appendChild($root);

    foreach($filenames as $filename) {

        $doc = new DOMDocument();
        $doc->load($filename);

        $xmlString = $doc->saveXML($doc->documentElement);

        $xpath = new DOMXPath($doc);
        $query = "//product";  // this is the name of the ROOT element

        $nodelist = $xpath->evaluate($query, $doc->documentElement);

        if( $nodelist->length > 0 ) {

            $node = $docList->importNode($nodelist->item(0), true);

            $xmldownload = $docList->createElement('document');
            $xmldownload->setAttribute("filename", $filename);
            $xmldownload->appendChild($node);

            $root->appendChild($xmldownload);
        }

    }

    echo $docList->saveXML();
?>
like image 42
SRM Avatar answered Jan 30 '23 23:01

SRM