Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concatenating xml files

Tags:

xml

xslt

msxml

I have several xml files, the names of which are stored in another xml file.

I want to use xsl to produce a summary of the combination of the xml files. I remember there was a way to do this with the msxml extensions (I'm using msxml).

I know I can get the content of each file using select="document(filename)" but I'm not sure how to combine all these documents into one.

21-Oct-08 I should have mentioned that I want to do further processing on the combined xml, so it is not sufficient to just output it from the transform, I need to store it as a node set in a variable.

like image 690
Richard A Avatar asked Oct 20 '08 05:10

Richard A


People also ask

How can I merge two XML files online?

To add files click anywhere in the blue area or on the Browse for file button to upload or drag and drop them. You can also add the documents by entering their URL in the URL cell. Click on the Merge button. Your MPP file will be uploaded and combined to the result format.

How do I combine PDF files with XML?

Open both files you want to combine. Highlight all the pages of the XML document, right click, and select "Extract Pages". Extract them all into a new document. Then just select the pages and drag them to the other pdf doc.


2 Answers

Here is just a small example of what you could do:

file1.xml:

<foo>
<bar>Text from file1</bar>
</foo>

file2.xml:

<foo>
<bar>Text from file2</bar>
</foo>

index.xml:

<index>
<filename>file1.xml</filename>
<filename>file2.xml</filename>

summarize.xsl:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:exsl="http://exslt.org/common"
    extension-element-prefixes="exsl">

  <xsl:variable name="big-doc-rtf">
      <xsl:for-each select="/index/filename">
        <xsl:copy-of select="document(.)"/>
      </xsl:for-each>
  </xsl:variable>

  <xsl:variable name="big-doc" select="exsl:node-set($big-doc-rtf)"/>

  <xsl:template match="/">
    <xsl:element name="summary">
      <xsl:apply-templates select="$big-doc/foo"/>
    </xsl:element>  
  </xsl:template>

  <xsl:template match="foo">
    <xsl:element name="text">
      <xsl:value-of select="bar"/>
    </xsl:element>  
  </xsl:template>

</xsl:stylesheet>

Applying the stylesheet to index.xml gives you:

<?xml version="1.0" encoding="UTF-8"?><summary><text>Text from file1</text><text>Text from file2</text></summary>

The trick is to load the different documents with the document function (extension function supported by almost all XSLT 1.0 processors), to output the contents as part of a variable body and then to convert the variable to a node-set for further processing.

like image 97
GerG Avatar answered Sep 18 '22 14:09

GerG


Assume that you have the filenames listed in a file like this:

<files>
    <file>a.xml</file>
    <file>b.xml</file>
</files>

Then you could use a stylesheet like this on the above file:

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

    <xsl:template match="/">
        <root>
            <xsl:apply-templates select="files/file"/>                          
        </root>
    </xsl:template>

    <xsl:template match="file">
        <xsl:copy-of select="document(.)"/>
    </xsl:template>
</xsl:stylesheet>
like image 45
Farthingworth Avatar answered Sep 21 '22 14:09

Farthingworth