0

I am making an API call and now I need to get a specific piece of data from the response. I am needing to get the DocumentID for the "Description" Invoice, which in the case below is 110107.

I have already created a method to get data from get a single tag by doing this:

public synchronized String getTagFromHTTPResponseAsString(String tag, String body) throws IOException {

    final Pattern pattern = Pattern.compile("<"+tag+">(.+?)</"+tag+">");
    final Matcher matcher = pattern.matcher(body);
    matcher.find();

    return matcher.group(1);

} // end getTagFromHTTPResponseAsString

However, my problem is with this result set, there are multiple fields with the same tag and I need a specific one. Here is the response:

<?xml version="1.0" encoding="utf-8"?>
<Order TrackingID="351535" TrackingNumber="TEST-843245" xmlns="">
  <ErrorMessage />
  <StatusDocuments>
    <StatusDocument NUM="1">
      <DocumentDate>7/14/2017 6:52:00 AM</DocumentDate>
      <FileName>4215.pdf</FileName>
      <Type>Sales Contract</Type>
      <Description>Uploaded Document</Description>
      <DocumentID>110098</DocumentID>
      <DocumentPlaceHolder />
    </StatusDocument>
    <StatusDocument NUM="2">
      <DocumentDate>7/14/2017 6:52:00 AM</DocumentDate>
      <FileName>Apex_Shortcuts.pdf</FileName>
      <Type>Other</Type>
      <Description>Uploaded Document</Description>
      <DocumentID>110100</DocumentID>
      <DocumentPlaceHolder />
    </StatusDocument>
    <StatusDocument NUM="3">
      <DocumentDate>7/14/2017 6:52:00 AM</DocumentDate>
      <FileName>CRAddend.pdf</FileName>
      <Type>Other</Type>
      <Description>Uploaded Document</Description>
      <DocumentID>110104</DocumentID>
      <DocumentPlaceHolder />
    </StatusDocument>
    <StatusDocument NUM="4">
      <DocumentDate>7/14/2017 6:52:00 AM</DocumentDate>
      <FileName>test.pdf</FileName>
      <Type>Other</Type>
      <Description>Uploaded Document</Description>
      <DocumentID>110102</DocumentID>
      <DocumentPlaceHolder />
    </StatusDocument>
    <StatusDocument NUM="5">
      <DocumentDate>7/14/2017 6:55:00 AM</DocumentDate>
      <FileName>Invoice.pdf</FileName>
      <Type>Invoice</Type>
      <Description>Invoice</Description>
      <DocumentID>110107</DocumentID>
      <DocumentPlaceHolder />
    </StatusDocument>
  </StatusDocuments>
</Order>

I tried creating and testing out my regular expression on https://regex101.com/ and got this RegEx to work there, but I cannot get it to translate over correctly into my Java code:

<Description>Invoice<\/Description>
      <DocumentID>(.*?)<\/DocumentID>
2
  • Don't use regexes to parse XML. Use an XML parser. Commented Jul 14, 2017 at 12:39
  • 1
    Regex is for String matching, not for XML parsing. I would recommend using one of the many xml parsing libraries. Additionally in my experience Regex can be awkward to use and maintain. Commented Jul 14, 2017 at 12:39

2 Answers 2

1

Try it with Jsoup

Example:

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class sssaa {
    public static void main(String[] args) throws Exception {
        String xml = "yourXML";        
        Document doc = Jsoup.parse(xml);
        Elements StatusDocuments = doc.select("StatusDocument");
        for(Element e : StatusDocuments){
            if(e.select("Description").text().equals("Invoice")){
                System.out.println(e.select("DocumentID").text());
            }           
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

What I have done to solve this is use StringBuilder to convert the response into a single string and then used this piece of code to get the DocumentID:

// Create the pattern and matcher
Pattern p = Pattern.compile("<Description>Invoice<\\/Description><DocumentID>(.*)<\\/DocumentID>");
Matcher m = p.matcher(responseText);

// if an occurrence if a pattern was found in a given string...
if (m.find()) {
    // ...then you can use group() methods.
    System.out.println("group0 = " + m.group(0)); // whole matched expression
    System.out.println("group1 = " + m.group(1)); // first expression from round brackets (Testing)
}

// Set the documentID for the Invoice 
documentID = m.group(1);

Looks like this is probably not the best way to go about doing this, but it is working for now. I will come back and try to clean this up with a more correct solution from suggestions given here.

1 Comment

@Eritrean answer works great and is much cleaner. I'm implementing that solution

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.