Using Axis2 services from Javascript (by removing the XML namespaces)

If you want to call an Axis2 service from Javascript you will face the problem that the XML response of an Axis2 service call contains XML namespaces – something Javascript doesn’t like in cross-browser-friendly way.
The idea to fix this issue is to make an XSLT transformation directly from Axis2 that removes the unnecessary namespaces.

First we need an XSLT transformation that will do the job:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="no"/>
 
<xsl:template match="/|comment()|processing-instruction()">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
</xsl:template>
 
<xsl:template match="*">
    <xsl:element name="{local-name()}">
      <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
</xsl:template>
 
<xsl:template match="@*">
    <xsl:attribute name="{local-name()}">
      <xsl:value-of select="."/>
    </xsl:attribute>
</xsl:template>
</xsl:stylesheet>

Then we’ll need a hand-made Axis2 conform MessageFormatter that uses the standard formatter for XML and performs the XSLT transformation on the result:

package de.marcusschiesser.axis2;
 
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.OutputStream;
 
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
 
import org.apache.axiom.om.OMOutputFormat;
import org.apache.axis2.AxisFault;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.transport.http.ApplicationXMLFormatter;
 
public class NamespaceLessXMLFormatter extends ApplicationXMLFormatter {
	private Transformer transformer;
	private AxisFault fault; 
 
	public NamespaceLessXMLFormatter() {
		super();
		TransformerFactory tFactory = TransformerFactory.newInstance();
		try {
			transformer = tFactory.newTransformer(new StreamSource(new File("removeNamespaces.xsl")));
		} catch (TransformerConfigurationException e) {
			fault = AxisFault.makeFault(e);
		}
	}
 
	@Override
	public void writeTo(MessageContext messageContext, OMOutputFormat format, OutputStream outputStream,
			boolean preserve) throws AxisFault {
		if(fault!=null) throw fault;
		try {
			ByteArrayOutputStream os = new ByteArrayOutputStream();
			super.writeTo(messageContext, format, os, preserve);
			ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
			transformer.transform(new StreamSource(is), new StreamResult(outputStream));
		} catch (TransformerException e) {
			throw AxisFault.makeFault(e);
		}
	}
 
}

(Don’t forget to adjust the path of removeNamespaces.xsl, so the formatter can find the .xsl!)

Finally just put the class of the newly created formatter in WEB-INF/classes of your Axis2 deployment and replace the reference in the axis2.xml configuration file.
For this just exchange the line:

<messageFormatter contentType="application/xml" class="org.apache.axis2.transport.http.ApplicationXMLFormatter"/>

with:

<messageFormatter contentType="application/xml" class="de.marcusschiesser.axis2.NamespaceLessXMLFormatter"/>

After a restart of your application server you should be able to use your Axis2 services from Javascript – Have fun!

Be Sociable, Share!

3 thoughts on “Using Axis2 services from Javascript (by removing the XML namespaces)

  1. Thanks for useful information. I want to remove the tag itself not just the namespace declaration. Do you know is there a way to do this?

  2. Hi, Thanks for the very useful post.
    I followed the steps above, but looks like writeTo() method is not being called and transformation is not happening.

    basically I included the logger statements in constructor and writeTo() method of ApplicationXMLFormatter class.

    But the logger statement in the writeTo() is not being printed in log file, although the one in constructor is being printed.

    Appreciate your help.

  3. where i create a xsl file in project directory my xml file is look like this

    {‘vbak_id’:’1000136′}

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>