Search code examples
jaxbunmarshallingstax

Stax parse doesn't return proper response


Hi ,

I am facing very strange issue while parsing SOAP Response with Jaxb. I am not able to get complete list of tags while parsing .Stax parser is able to parse only one tag ,its not giving any error or exception.However if I try to format the xml response(which is stored in string) Everything works perfectly fine. Here is what I am doing to parse it :-

  public void parseResponse(){
     String response="<SOAP:Body><response><result><myTag></myTag><myTag></myTag>/result</response</SOAP:Body>";

     getUnmarshalledObject(response,myTag,MyTag.class,"com.mylearning.parseXml");
     } 





     public  <T> List<T> getUnmarshalledObject( String response ,String TAG_TO_SEARCH ,Class<T> clazz , String basePkg) 
                                    throws XMLStreamException, JAXBException{
                            Reader reader = new StringReader(response);
                            XMLInputFactory xif = XMLInputFactory.newInstance();
                            XMLStreamReader xsr = xif.createXMLStreamReader(reader);

                            List<T> listOfUnmarshalledObjects = new ArrayList<T>();
                            while (xsr.hasNext()) {
                                if (xsr.getEventType() == XMLStreamReader.START_ELEMENT && TAG_TO_SEARCH.equals(xsr.getLocalName())) {
                                        T unmarshalledObj = unmarshalXml( clazz ,xsr, basePkg);
                                        listOfUnmarshalledObjects .add(unmarshalledObj);
                                    }
                                    xsr.next();
                                }
                            return listOfUnmarshalledObjects;
                        }

Here are different use cases of the problem:-

            Case 1:- Input String response is unformatted.
            Result :- listOfUnmarshalledObjects is 1.

            Case 2:- Format response with response.replaceAll("><",">\n<"); 
            Result:- listOfUnmarshalledObjects is 2.

            Case 3 : Input String unformatted , just give space b/w </myTag><myTag>
            Result:  listOfUnmarshalledObjects is 2.

            I tried my best to explain the question, please help me.                    
            > Blockquote

Solution

  • I turns out that main culprit was missing else condition. Parsing cursor was able to find the first block of ..tag but once it’s done with it , xsr.next is also getting executed in each iteration.

    So in case where xml is not formatted :- 1. Parser finds the first complete block of and store it in list , now cursor is at next tag but before control goes to the next iteration xsr.next gets executed and moves cursor to the next immediate tag.

    In case of formatted xml :- 1. There will be \n character between two continuous block \n so even if xsr.next gets executed at each iteration it will just eat \n character and cursor will be right on track to parse next block of tag.

    Here is the updated code with else condition :-

    while (xsr.hasNext()) {
       if (xsr.getEventType() == XMLStreamReader.START_ELEMENT && TAG_TO_SEARCH.equals(xsr.getLocalName())) {
              T unmarshalledObj = unmarshalXml( clazz ,xsr, basePkg);
              listOfUnmarshalledObjects .add(unmarshalledObj);
          }else{
                xsr.next();
               }
         }