Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to read a pom.xml ('Project Object Model' of Maven) and extract the version information. Here is an example:

<?xml version="1.0" encoding="UTF-8"?><project 
xmlns="" xmlns:xsi="" xsi:schemaLocation="">


How can I extract the version '1.0.74-SNAPSHOT' from above?

Would love to be able to do so using simple bash scripting sed or awk. Otherwise a simple python is preferred.


  1. Constraint

    The linux box is in a corporate environment so I can only use tools that are already installed (not that I cannot request utility such as xml2, but I have to go through a lot of red-tape). Some of the solutions are very good (learn a few new tricks already), but they may not be applicable due to the restricted environment

  2. updated xml listing

    I added the dependencies tag to the original listing. This will show some hacky solution may not work in this case

  3. Distro

    The distro I am using is RHEL4

share|improve this question
Is this… sufficient? – bbaja42 Dec 20 '11 at 22:08
Not really. There are a lot of version tag in the xml (e.g. under dependencies tag). I only want '/project/version' – Anthony Kong Dec 20 '11 at 22:20
Which xml-related tools and libraries are available? Are jvm-based soltuions OK? – Vi. Dec 20 '11 at 23:22
So far I can tell xml2, xmlgrep and perl XML module are not present. Most unix command-line utilities are present. The distro is Redhat EL 4. – Anthony Kong Dec 20 '11 at 23:38
(I couldn't add a comment so I have to reply as an answer, overkill somewhat) Some great answers can be found here.....… – JStrahl Jan 18 '13 at 10:12

13 Answers 13

up vote 12 down vote accepted

xml2 can convert xml to/from line-oriented format:

xml2 < pom.xml  | grep /project/version= | sed 's/.*=//'
share|improve this answer

Other way: xmlgrep and XPath:

xmlgrep --text_only '/project/version' pom.xml

Disadvantage: slow

share|improve this answer

Clojure way. Requires only jvm with special jar file:

java -cp clojure.jar clojure.main -e "(use 'clojure.xml) (->> ( \"pom.xml\") (clojure.xml/parse) (:content) (filter #(= (:tag %) :version)) (first) (:content) (first) (println))"

Scala way:

java -Xbootclasspath/a:scala-library.jar -cp scala-compiler.jar -e 'import scala.xml._; println((XML.load(new"pom.xml")) match { case <project>{children @ _*}</project> => for (i <- children if (i  match { case <version>{children @ _*}</version> => true; case _ => false;  }))  yield i })(0) match { case <version>{Text(x)}</version> => x })'

Groovy way:

java -classpath groovy-all.jar groovy.ui.GroovyMain -e 'println (new XmlParser().parse(new File("pom.xml")).value().findAll({"version" }).first().value().first())'
share|improve this answer
This is awesome! Great idea! – Anthony Kong Dec 21 '11 at 0:06
I'm waiting for Vi's x86-machine-code-in-hex way. – RedGrittyBrick Dec 21 '11 at 16:33

Hacky way:

perl -e '$_ = join "", <>; m!<project[^>]*>.*\n(?:    |\t)<version[^>]*>\s*([^<]+?)\s*</version>.*</project>!s and print "$1\n"' pom.xml

Relies on correct indentation of the required <version>

share|improve this answer
Thanks for the suggestion, but unfortunately it will not return what I want. Please see the updated pom model. – Anthony Kong Dec 20 '11 at 23:14
Returns "1.0.74-SNAPSHOT". Note that I changed the script after reading about multiple <version> things. – Vi. Dec 20 '11 at 23:17
Note: this solution is provided "just for fun" and is not intended to be used in actual product. Better use xml2/xmlgrep/XML::Simple solution. – Vi. Dec 20 '11 at 23:18
Thanks! even though it is 'just for fun' but it is probably the 'most suitable' solution by far because it has minimum number of dependencies: It only requires perl ;-) – Anthony Kong Dec 20 '11 at 23:22
What about doing it from Java? Using pom files implies having JVM installed. – Vi. Dec 20 '11 at 23:25

Using python

$ python -c 'from xml.etree.ElementTree import ElementTree; print ElementTree(file="pom.xml").findtext("{}version")'

Using xmlstarlet

$ xml sel -N x="" -t -m 'x:project/x:version' -v . pom.xml

Using xmllint

$ echo -e 'setns x=\ncat /x:project/x:version/text()' | xmllint --shell pom.xml | grep -v /
share|improve this answer
cat (//x:version)[1]/text() when using xmllint also works! – kev Dec 21 '11 at 5:50

Here's an alternative in Perl

$ perl -MXML::Simple -e'print XMLin("pom.xml")->{version}."\n"'

It works with the revised/extended example in the questions which has multiple "version" elements at different depths.

share|improve this answer
Slow, (although faster than xmlgrep) – Vi. Dec 20 '11 at 22:58

Work out a very clumsy, one-liner solution

python -c "from xml.dom.minidom import parse;dom = parse('pom.xml');print [n for n in dom.getElementsByTagName('version') if n.parentNode == dom.childNodes[0]][0].toxml()" | sed -e "s/.*>\(.*\)<.*/\1/g"

The sed at the end is very ugly but i was not able to print out the text of the node with mindom alone.

Update from _Vi:

Less hacky Python version:

python -c "from xml.dom.minidom import parse;dom = parse('pom.xml');print [i.childNodes.item(0).nodeValue for i in dom.firstChild.childNodes if i.nodeName == 'version'].pop()"

Update from me

Another version:

    python -c "from  xml.dom.minidom import parse;dom = parse('pom.xml');print [ for n in dom.childNodes[0].childNodes if n.firstChild and n.tagName == 'version']"
share|improve this answer

XSLT way:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="">
        <xsl:output method="text"/>

        <xsl:template match="/">
                <xsl:for-each select="*[local-name()='project']">
                    <xsl:for-each select="*[local-name()='version']">
                        <xsl:value-of select="text()"/>
xalan -xsl x.xsl -in pom.xml
share|improve this answer
If xsltproc is on your system, and it probably is as libxslt is on RHEL4, then you can use it and the above stylesheet to output the tag, i.e. xsltproc x.xsl prom.xsl. – fpmurphy1 Dec 21 '11 at 5:12

if "There are a lot of version tag in the xml" then you better forget about doing it with "simple tools" and regexps, that won't do.

try this python (no dependencies):

from xml.dom.minidom import parse

dom = parse('pom.xml')
project = dom.getElementsByTagName('project')[0]
for node in project.childNodes:
    if node.nodeType == node.ELEMENT_NODE and node.tagName == 'version':
        print node.firstChild.nodeValue
share|improve this answer
What exactly does this script do? – Simon Sheehan Dec 22 '11 at 1:41
it loads the XML as a DOM structure using Python's minidom implementation: the idea is to grab the <project> tag that is unique and then iterate over its child nodes (direct childs only) to find the tag <version> that we're looking for and not other tags with the same name in other places. – Samus_ Dec 22 '11 at 15:17

Here is a one-liner using sed:

sed '/<dependencies>/,/<\/dependencies>/d;/<version>/!d;s/ *<\/\?version> *//g' pom.xml
share|improve this answer
Relies on absence of parameters in elements and that extra <version>s can be only inside dependencies. – Vi. Dec 21 '11 at 16:33
Return_text_val=$(xmllint --xpath "//*[local-name()='$TagElmnt']" $FILE )

Here, try this:

$TagElmnt - TagName
$FILE - xml file to parse
share|improve this answer
This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post - you can always comment on your own posts, and once you have sufficient reputation you will be able to comment on any post. – Wes Sayeed May 14 '15 at 7:42
sed -n "/<name>project-parent/{n;s/.*>\(.*\)<.*/\1/p;q}" pom.xml

The -n option avoids printing non-matching lines; first match (/.../) is on the line before the one with wanted text; the n command skips to next line, where s extracts relevant info thru a capturing group (\(...\)), and a backreference (\1). p prints out, q quits.

share|improve this answer
Can you expand your answer to explain this? Thanks. – fixer1234 Oct 27 '15 at 1:42

I know your question says Linux but if you have the need to do this on Windows without the need of any 3rd party tools such that you can put it in a batch file, Powershell can extract any node from the your pom.xml file like so:

powershell -Command "& {select-xml //pom:project/pom:properties/pom:mypluginversion -path pom.xml -Namespace  @{pom=''} | foreach {$_.Node.Innerxml}}" > myPluginVersion.txt
share|improve this answer

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .