GlobalVariable
GlobalVariable

Reputation: 181

How to retrieve xpath from pom.xml with libxmljs

My issue has to do with namespaces.

I am trying to retrieve the value of the element from a maven pom xml. My libxml-js code is as follows:

var fs = require('fs');
var libxml = require('libxmljs');

fs.readFile('pom.xml', 'utf8', function (err,data) {
   var doc = libxml.parseXmlString(data);
   var root = doc.root();
   var version = root.get("parent/version");
   console.log(version.text());
}

If I use pom.xml without the namespace declarations as follows, it finds the element and prints "2.0.1-SNAPSHOT" correctly.

<?xml version="1.0" encoding="UTF-8"?>
<project>
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <artifactId>acme-main</artifactId>
        <groupId>com.acme</groupId>
        <version>2.0.1-SNAPSHOT</version>
    </parent>
</project>

However, as soon as I put back the original (valid and required) namespace declarations as follows, I get an exception because it's not able to find that element.

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <artifactId>acme-main</artifactId>
        <groupId>com.acme</groupId>
        <version>2.0.1-SNAPSHOT</version>
    </parent>
</project>

My question is, how do I retrieve the /project/parent/version value from the default namespace while retaining the namespace declarations in my pom?

Thanks!

PS: I am open to using other node libraries than libxml-js if there are any suggestions.

Upvotes: 0

Views: 1323

Answers (2)

I managed to do this with the following:

//defNS would be 'http://maven.apache.org/POM/4.0.0'
let defNS = xmlDoc.root().namespace().href(); 
let version = xmlDoc.get('/xmlns:project/xmlns:version',defNS).text();

My understanding is that the xmlns attribute is a default namespace that affects every element in the document so it needs to be specified when searching the document. This effectively returns some data as opposed to 'undefined' which is what I was getting before using namespaces.

Upvotes: 4

Gaurav Gupta
Gaurav Gupta

Reputation: 4691

I have used xml2js and it works like charm for me all the time.

If you decide to use xml2js then below is the source for your problem:

var parseString = require('xml2js').parseString,
    fs = require('fs');

fs.readFile('./pom.xml', function(err, data) {
    parseString(data, function (err, result) {
        console.dir(result['project']['parent'][0]['version'][0]);
    });
});

Upvotes: 0

Related Questions