Wednesday, October 19, 2016

Rename or Remove Namespace in XML file

Recently while working with web services, I stumbled on a problem where in I had to read the the XMLs and convert them into object.

Now this can be done easily, if you have WSDL but I dont usually encounter easy problems.

All I had was an XML and I have manually create an object for it. However, JAXB unmarshaller wont convert it because of namespaces. Hence, I wrote this program to remove namespaces which can be used to rename namespaces as well.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
  * Recursively renames the namespace of a node.
  * 
  * @param node
  *            the starting node.
  * @param namespace
  *            the new namespace. Supplying <tt>null</tt> removes the namespace.
  */
 public static void renameNamespace(Node node, String namespace) {

  Document document = node.getOwnerDocument();
  if (node.getNodeType() == Node.ELEMENT_NODE) {
   String nodename = node.getNodeName();
   Element e = (Element) node;
   NamedNodeMap attrs = node.getAttributes();
   String attributeName = null;
   //rename the namespace in the tag
   if (nodename.lastIndexOf(":") > 0) {
    nodename = (String) nodename.subSequence(nodename.lastIndexOf(":") + 1, nodename.length());
    nodename = namespace + ":" + nodename;
   }
   document.renameNode(node, namespace, nodename);
  }
  NodeList list = node.getChildNodes();
  //call recursively
  for (int i = 0; i < list.getLength(); ++i) {
   renameNamespace(list.item(i), namespace);
  }
 }

Rename Namespaces



 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
 /**
  * Recursively removes the namespace of a node.
  * 
  * @param node
  *            the starting node.
  * @param namespace
  *            the new namespace. Supplying <tt>null</tt> removes the namespace.
  */
 public static void removeNamespace(Node node) {

  Document document = node.getOwnerDocument();
  if (node.getNodeType() == Node.ELEMENT_NODE) {
   String nodename = node.getNodeName();
   Element e = (Element) node;
   NamedNodeMap attrs = node.getAttributes();
   String attributeName = null;
   //remove the tag which defines namespace
   for (int i = 0; i < attrs.getLength(); i++) {
    if (attrs.item(i) != null) {
     attributeName = attrs.item(i).getNodeName();
     if (attributeName.startsWith("xmlns")) {
      e.removeAttribute(attrs.item(i).getNodeName());
      i--;
     }
    }
   }
   //remove the namespace in the tag
   if (nodename.lastIndexOf(":") > 0) {
    nodename = (String) nodename.subSequence(nodename.lastIndexOf(":") + 1, nodename.length());
   }
   document.renameNode(node, null, nodename);
  }
  NodeList list = node.getChildNodes();
  //call recursively
  for (int i = 0; i < list.getLength(); ++i) {
   removeNamespace(list.item(i), namespace);
  }
 }

Remove Namespaces




 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 private static void print(PrintStream out, Document doc) throws IOException {

  OutputFormat fmt = new OutputFormat();
  fmt.setIndenting(true);
  XMLSerializer ser = new XMLSerializer(out, fmt);
  ser.serialize(doc);
 }

 public static void main(String[] args) {

  try {
   File fXmlFile = new File("src\\test\\xyz.xml");
   DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
   DocumentBuilder dBuilder;
   dBuilder = dbFactory.newDocumentBuilder();
   Document doc = dBuilder.parse(fXmlFile);
   renameNamespace(doc.getDocumentElement().getParentNode(), "renamed");
   //removeNamespace(doc.getDocumentElement().getParentNode());
   print(System.out, doc);
  } catch (ParserConfigurationException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (SAXException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  } catch (IOException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
 }

Test Code



After removing the namespaces the unmarshaller worked like charm.  

No comments:

Post a Comment