How to mask XML elements in Java while printing to log files

In this article, we will write a Java program to mask elements in an XML while printing.

This program traverses through the xml and if it finds sensitive elements like userid and password, it masks them and print the rest of the xml as is.

We have already covered converting an XML document to String and vice versa before and we will using those functions here.

You can refer the corresponding article here :

String to XML and XML to String in Java
 
The masking function maskElements() checks the elements and if it matches the elements to be masked, it replaces the value with asterisks (*).

public static void maskElements(Node node) {
  NodeList nodeList = node.getChildNodes();

  for (int i = 0; i < nodeList.getLength(); i++) {
    Node currentNode = nodeList.item(i);
    // recursively call maskElements until you find a Leaf node
    if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
      maskElements(currentNode);
    } else if (currentNode.getNodeType() == Node.TEXT_NODE) {
      // leaf node.. apply masking logic
      String name = currentNode.getParentNode().getNodeName();
      if (name != null && elementsToMask.contains(name)) {
        currentNode.setTextContent("********");
      }
    }

  }
}

 

Here is the complete program :

package temp;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

public class XMLMaskingDemo {

  static List<String> elementsToMask = Arrays.asList("user", "password");

  public static void main(String[] args) {

    String inputXML = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"
        + "<Tutorial><user>test</user><password>abcdef</password><technology>Java, Big data, Database</technology>"
        + "<address>topjavatutorial.com</address></Tutorial>";

    System.out.println("Input XML : \n" + inputXML);

    String maskedXML = maskXML(inputXML);

    // Print the masked XML
    System.out.println("\nXML after masking : \n" + maskedXML);

  }

  private static String maskXML(String xmlString) {
    String str = null;
    try {
      // Convert string to XML document
      Document document = toXmlDocument(xmlString);

      // Now mask the required fields in the XML
      maskElements(document.getDocumentElement());

      // Convert document object to string
      str = toXmlString(document);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return str;

  }

  private static Document toXmlDocument(String str)
      throws ParserConfigurationException, SAXException, IOException {

    DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
        .newInstance();
    DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
    Document document = docBuilder.parse(new InputSource(new StringReader(
        str)));

    return document;
  }

  private static String toXmlString(Document document)
      throws TransformerException {
    TransformerFactory transformerFactory = TransformerFactory
        .newInstance();
    Transformer transformer = transformerFactory.newTransformer();
    DOMSource source = new DOMSource(document);
    StringWriter strWriter = new StringWriter();
    StreamResult result = new StreamResult(strWriter);

    transformer.transform(source, result);

    return strWriter.getBuffer().toString();

  }

  public static void maskElements(Node node) {
    NodeList nodeList = node.getChildNodes();

    for (int i = 0; i < nodeList.getLength(); i++) {
      Node currentNode = nodeList.item(i);
      // recursively call maskElements until you find a Leaf node
      if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
        maskElements(currentNode);
      } else if (currentNode.getNodeType() == Node.TEXT_NODE) {
        // leaf node.. apply masking logic
        String name = currentNode.getParentNode().getNodeName();
        if (name != null && elementsToMask.contains(name)) {
          currentNode.setTextContent("********");
        }
      }

    }
  }
}

Output :


Input XML : 
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Tutorial><user>test</user><password>abcdef</password><technology>Java, Big data, Database</technology><address>topjavatutorial.com</address></Tutorial>

XML after masking : 
<?xml version="1.0" encoding="UTF-8"?><Tutorial><user>********</user><password>********</password><technology>Java, Big data, Database</technology><address>topjavatutorial.com</address></Tutorial>

© 2017, https:. All rights reserved. On republishing this post, you must provide link to original post

Leave a Reply.. code can be added in <code> </code> tags