Merge XML files with configurable rules (context: Maven POMs, Java)
- by Patrick Bergner
Hi,
I'm currently writing some kind of a Maven POM preprocessor that assembles a POM for a project from multiple input files (basically a template and a module specific file). The files are hierarchically ordered (template = most general, module specific = least general). The problem is now to merge these files into a single POM file.
Long story short or if you're not familiar with Maven: a POM looks like this (shortened):
<project>
<modelVersion>4.0.0</modelVersion>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
</dependency>
</dependencies>
</project>
Basically the merger shall replace all values of the more general file with the values of the more specific file (i.e. singletons, e.g. the <modelVersion> above) but there are certain elements where the merger shall add the more certain element to a parent (i.e. collections, e.g. <dependency> elements shall always be added to the <dependencies> element and no <dependency> element shall be replaced by another).
A more detailed example with definition of desired output:
File A:
<project>
<modelVersion>A</modelVersion>
<dependencies>
<dependency>
<groupId>groupIdA</groupId>
<artifactId>artifactIdA</artifactId>
</dependency>
</dependencies>
</project>
File B:
<project>
<modelVersion>B</modelVersion>
<dependencies>
<dependency>
<groupId>groupIdB</groupId>
<artifactId>artifactIdB</artifactId>
</dependency>
</dependencies>
</project>
Desired output:
<project>
<modelVersion>B</modelVersion>
<dependencies>
<dependency>
<groupId>groupIdA</groupId>
<artifactId>artifactIdA</artifactId>
</dependency>
<dependency>
<groupId>groupIdB</groupId>
<artifactId>artifactIdB</artifactId>
</dependency>
</dependencies>
</project>
The set of collection type elements are known and should be configurable (preferably via a set of XPath expressions).
A Java based solution is appreciated.
What looked most promising so far was the tool mentioned here but the MERGE action produces something like
<dependency>
<groupId>groupIdAgroupIdB</groupId>
<artifactId>artifactIdAartifactIdB</artifactId>
</dependency>
when merging, which is not what I need.
Any ideas? Thanks for your help!