I am using XSLT to combine XML files. This allows me to set up a merge operation to just merge content together or merge at a certain level. This is a bit more work (and XSLT syntax is special), but super flexible. A few things you need here.
a) Include an additional file b) Copy the source file 1: 1 c) Create your merge point with or without duplication prevention.
a) In the beginning I
<xsl:param name="mDocName">yoursecondfile.xml</xsl:param> <xsl:variable name="mDoc" select="document($mDocName)" />
this allows you to specify a second file using $ mDoc
b) Instructions for copying the source tree 1: 1 are 2 templates:
<xsl:template match="*"> <xsl:element name="{name()}"> <xsl:apply-templates select="@*" /> <xsl:apply-templates /> </xsl:element> </xsl:template> <xsl:template match="@*"> <xsl:attribute name="{name()}"><xsl:value-of select="." /></xsl:attribute> </xsl:template>
With nothing else, you are not getting a 1: 1 copy of your first source file. Works with any type of XML. The unifying part is file. Suppose you have event elements with an event identifier attribute. You do not want duplicate identifiers. The template will look like this:
<xsl:template match="events"> <xsl:variable name="allEvents" select="descendant::*" /> <events> <xsl:apply-templates /> <xsl:for-each select="$mDoc/logbook/server/events/event"> <xsl:variable name="curID" select="@id" /> <xsl:if test="not ($allEvents[@id=$curID]/@id = $curID)"> <xsl:element name="event"> <xsl:apply-templates select="@*" /> <xsl:apply-templates /> </xsl:element> </xsl:if> </xsl:for-each> </properties> </xsl:template>
Of course, you can compare other things like tag names, etc. It is also up to you how deep the merger is. If you do not have a key for comparison, the design becomes simpler, for example. for the magazine:
<xsl:template match="logs"> <xsl:element name="logs"> <xsl:apply-templates select="@*" /> <xsl:apply-templates /> <xsl:apply-templates select="$mDoc/logbook/server/logs/log" /> </xsl:element>
To run XSLT in Java, use this:
Source xmlSource = new StreamSource(xmlFile); Source xsltSource = new StreamSource(xsltFile); Result xmlResult = new StreamResult(resultFile); TransformerFactory transFact = TransformerFactory.newInstance(); Transformer trans = transFact.newTransformer(xsltSource); // Load Parameters if we have any if (ParameterMap != null) { for (Entry<String, String> curParam : ParameterMap.entrySet()) { trans.setParameter(curParam.getKey(), curParam.getValue()); } } trans.transform(xmlSource, xmlResult);
or you download Saxon SAX Parser and do it from the command line (Linux shell example):
#!/bin/bash notify-send -t 500 -u low -i gtk-dialog-info "Transforming $1 with $2 into $3 ..."
Ymmv