I need to extract the Maven GAV (groupId, artifactId, version) from a large number of pom.xml
files. Not all of the POMs have a parent POM declaration, so the inheritance between parent GAV and project GAV needs to be taken into account.
I'd only like to use tools that can be easily scripted in a linux shell, e.g. bash.
The GAV coordinate standard is the foundation for Maven's ability to manage dependencies. This set of coordinates is often referred to as a GAV coordinate, which is short for “Group, Artifact, Version coordinate.”"
The pom. xml file contains information of project and configuration information for the maven to build the project such as dependencies, build directory, source directory, test source directory, plugin, goals etc.
The POM file is named pom. xml and should be located in the root directory of your project. A project divided into subprojects will typically have one POM file for the parent project, and one POM file for each subproject.
grep -v '\[' <( mvn help:evaluate -Dexpression="project.groupId" 2>/dev/null &&
mvn help:evaluate -Dexpression="project.artifactId" 2>/dev/null &&
mvn help:evaluate -Dexpression="project.version" 2>/dev/null )
The best solution I could find is using an XSL transformation. Create a file extract-gav.xsl
with the following content:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:pom="http://maven.apache.org/POM/4.0.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/pom:project">
<!-- this XML element just serves as a bracket and may be omitted -->
<xsl:element name="artifact">
<xsl:text> </xsl:text>
<!-- process coordinates declared at project and project/parent -->
<xsl:apply-templates select="pom:groupId|pom:parent/pom:groupId" mode="copy-coordinate"/>
<xsl:apply-templates select="pom:artifactId|pom:parent/pom:artifactId" mode="copy-coordinate"/>
<xsl:apply-templates select="pom:version|pom:parent/pom:version" mode="copy-coordinate"/>
</xsl:element>
</xsl:template>
<xsl:template match="*" mode="copy-coordinate">
<!-- omit parent coordinate if same coordinate is explicitly specified on project level -->
<xsl:if test="not(../../*[name(.)=name(current())])">
<!-- write coordinate as XML element without namespace declarations -->
<xsl:element name="{local-name()}">
<xsl:value-of select="."/>
</xsl:element>
<xsl:text> </xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
This transformation can then be invoked in a shell (assuming that you have the libxslt installed) with th command xsltproc extract-gav.xsl pom.xml
This produces the output in the following format:
<artifact>
<groupId>org.example.group</groupId>
<artifactId>example-artifact</artifactId>
<version>1.2.0</version>
</artifact>
If you need a different format, the XSL transformation should be easy enough to adapt so that it suits your needs. E.g. the following transformation writes the GAV as tab-separated plain text:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:pom="http://maven.apache.org/POM/4.0.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/pom:project">
<!-- process coordinates declared at project and project/parent -->
<xsl:apply-templates select="pom:groupId|pom:parent/pom:groupId" mode="copy-coordinate"/>
<xsl:apply-templates select="pom:artifactId|pom:parent/pom:artifactId" mode="copy-coordinate"/>
<xsl:apply-templates select="pom:version|pom:parent/pom:version" mode="copy-coordinate"/>
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="*" mode="copy-coordinate">
<xsl:if test="not(../../*[name(.)=name(current())])">
<xsl:value-of select="."/>
<xsl:text>	</xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With