0

I have a XML string in one my java String objects as below:

<Record><op>Add</op><sensdata>400188711111</sensdata><id>4</id><a1>1111201090467034</a1></Record>

I need to get the data between sensdata tag and mask it something like 4001887XXXXX and prepare the xml string as below and log it.

<Record><op>Add</op><sensdata>4001887XXXXX</sensdata><id>4</id><a1>1111201090467034</a1></Record>

sensdata tag can be in lower or upper.

What is the better way to do it? Do i have to use some String operations or Regex or XML parser to do it?

I have a small query attached to this question. If i need the data between

<Record> </Record>

i.e

<op>Add</op><sensdata>4001887XXXXX</sensdata><id>4</id><a1>1111201090467034</a1>

Can i get using the xml parser. I am able to get the values like Add4001887XXXXX41111201090467034. But not with tags.

Anita
  • 185
  • 1
  • 6
  • 24

5 Answers5

2

You can also use XPath expressions to fetch the required data.

So, the solution could be:

    String xml = "<Record><op>Add</op><sensdata>400188711111</sensdata><id>4</id>"
            + "<a1>1111201090467034</a1></Record>";
    DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = null;
    try {
        builder = builderFactory.newDocumentBuilder();
    } catch (ParserConfigurationException e) {
        e.printStackTrace();  
    }
    Document document = builder.parse(new ByteArrayInputStream(xml.getBytes()));
    XPath xPath =  XPathFactory.newInstance().newXPath();
    String data = xPath.compile("/Record/sensdata").evaluate(document);
    System.out.println(data);
oardic
  • 212
  • 1
  • 3
1

As your strings contain XML you should use an XML parser. A proper example can be found here. On top of that a proper solution for your issue would be:

ByteArrayInputStream stream = new ByteArrayInputStream("<Record><op>Add</op><sensdata>400188711111</sensdata><id>4</id><a1>1111201090467034</a1></Record>".getBytes());
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = builder.parse(stream);

NodeList sensdata = document.getDocumentElement().getElementsByTagName("sensdata");

Now you have the node list of sensdata. You can further manipulate it. To use the string value of the given node you can proceed as follows:

String sensData = sensdata.item(0).getTextContent();

Probably it would be advisable to write defensive code in this situation, to avoid a NPE so, the above solution should be guarded:

if (sensdata.getLength() > 0) {
   String sensData = sensdata.item(0).getTextContent();        
}

As pointed out also in other answers one can use also XPath:

XPath xPath = XPathFactory.newInstance().newXPath();
String data = xPath.compile("/Record/sensdata").evaluate(document);
Community
  • 1
  • 1
Olimpiu POP
  • 5,001
  • 4
  • 34
  • 49
0

This is if you don't want to use any XML parsers.

You can use toLowerCase() before trying to find sensdata. Don't use you original string to retain case sensitive data use a copied string. And then use same indexes for the manipulating the original string.

Example

int startIndex = yourCopiedString.toLowerCase().indexOf("<sensdata>")+10;
int endIndex = yourCopiedString.toLowerCase().indexOf("</sensdata>");
String dataPart = yourCopiedString.substring(startIndex, endIndex);

For replacing :

String newEncodedString =  yourOriginalString.replace(yourOriginalString.substring(startIndex,endIndex), "XXXXXXXX");

If there is repetition of given substring then try this.

String newEncodedString = yourOriginalString.substring(0,startIndex)+ "XXXXXXXX"+yourOriginalString.substring(endIndex,yourOriginalString.lenght);
StackFlowed
  • 6,664
  • 1
  • 29
  • 45
0

Try this

String str = "<Record><op>Add</op><sensdata>400188711111</sensdata><id>4</id><a1>1111201090467034</a1></Record>"

int start = str.indexOf("<sensdata>");
int end = str.indexOf("</sensdata>");
String sendDataVal = str.substring(start+10, end);
-1

Two ways to go here i think: If it's very unlikely this task will change, a simple regex can solve it for you and a one line code. If the problem becomes structured, or your app works with a lot of xml, you probably want to parse it and operate dynamically.

a simple regex could be:

".*<[sS]ensdata>(.*)</[sS]ensdata>.*", group 1 ( "$1" ) will be your value.
Attila Neparáczki
  • 466
  • 1
  • 6
  • 14