0

My code finishes like this:

        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        Source sourceContent = soapResponse.getSOAPPart().getContent();
        System.out.print("\nResponse SOAP Message = ");
        StreamResult result = new StreamResult(System.out);
        transformer.transform(sourceContent, result);

and it has this output in console(result is in ONE OUTPUT line but I will copy paste it like pretty xml just to be more clear).

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <soap:Body>
    <VerifyEmailResponse xmlns="http://ws.cdyne.com/">
      <VerifyEmailResult>
        <ResponseText>Mail Server will accept email</ResponseText>
        <ResponseCode>3</ResponseCode>
        <LastMailServer>gmail-smtp-in.l.google.com</LastMailServer>
        <GoodEmail>true</GoodEmail>
      </VerifyEmailResult>
    </VerifyEmailResponse>
  </soap:Body>
</soap:Envelope>

So this works completly OK.Now if I want to have just ResponseText or ResponseCode value and to put those in some fields how can I process this result to XML and how to get that XML element?

Also I looked this question Convert StreamResult to string or xml but I do not see relation to my our question since I already have in my class code from the ANSWER but I am not able to process RESULT (to have it as XML which I can process additionally) if I add just

StringWriter writer = new StringWriter();
String resultString2=writer.toString();

I do not have reference to my RESULT variable which already has output.

I tried this also:

result.getOutputStream().toString();

but result is

java.io.PrintStream@3b9a45b3

result.toString(); does not give me desired result either

How to get this output to XML element from which I can retrieve and get specific XML element?

Thank you in advance,

Veljko
  • 1,708
  • 12
  • 40
  • 80
  • Why don't you use DOM parsers to parse your xml and get the node attributes – Pradeep Jun 27 '17 at 10:30
  • Hi can you tell me how to convert this result variable to DOM in order to be able to get specific XML element? Thanks – Veljko Jun 27 '17 at 10:32
  • RESULT must be returned in this way since I am using some already existing class. But now I want this to convert to DOM or XML in order to be able to get specific XML elements from this full output – Veljko Jun 27 '17 at 10:35
  • Did you saw this – Pradeep Jun 27 '17 at 10:38
  • https://stackoverflow.com/questions/23219728/convert-streamresult-to-string-or-xml – Pradeep Jun 27 '17 at 10:38
  • Especially murasing answer – Pradeep Jun 27 '17 at 10:39
  • If you are getting xml as response then you can use any dom parsers and format it to your requirement .https://www.mkyong.com/java/how-to-read-xml-file-in-java-dom-parser/ – Pradeep Jun 27 '17 at 10:40
  • @Pradeep I saw that link and I tried result.getOutputStream().toString(); but wrong result is presented. I need XML stucture in order to get specific xml element. Can you please post how I can use DOM parser on my StreamResult result variable??? Please post that how it can be converted and manipulated further . Thanks – Veljko Jun 27 '17 at 10:46

1 Answers1

1

In order to get the desired elements for e.g. ResponseCode, ResponseText from the output string which is an xml , you could use the following:

Because your xml has namespaces, xpath should be aware of that. So you set namespacecontext using xpath.setNameSpaceContext(ns); like below

TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
Source sourceContent = soapResponse.getSOAPPart().getContent();
System.out.print("\nResponse SOAP Message = ");

StringWriter sw = new StringWriter();
transformer.transform( sourceContent, new StreamResult( sw ) );

InputSource inputSource = new InputSource( new StringReader( sw.toString() ) );
XPath xpath = XPathFactory.newInstance().newXPath();

javax.xml.namespace.NamespaceContext ns = new javax.xml.namespace.NamespaceContext()
 {

    @Override
    public String getNamespaceURI(String prefix) {
        if ( "soap".equals( prefix ) )
        {
            return "http://schemas.xmlsoap.org/soap/envelope/";
        }
        else if ( "xsi".equals( prefix ) )
        {
            return "http://www.w3.org/2001/XMLSchema-instance";
        }
        else if ( "xsd".equals( prefix ) )
        {
            return "http://www.w3.org/2001/XMLSchema";
        }
        else if ( "xml".equals( prefix ) )
        {
            return javax.xml.XMLConstants.XML_NS_URI;
        }
        else if( "responsens".equals( prefix ) )
        {
            return "http://ws.cdyne.com/";
        }


        return javax.xml.XMLConstants.NULL_NS_URI;

    }

    @Override
    public String getPrefix(String namespaceURI) {
                return null;
    }

    @Override
    public Iterator<?> getPrefixes(String namespaceURI) {
                return null;
    }

 };
 xpath.setNamespaceContext(ns);
 Object obj = xpath.evaluate("//responsens:ResponseText/text()", inputSource, XPathConstants.STRING );
 if ( obj != null ) 
 { 
       String responseText = obj.toString();
       System.out.println("Response text : " + responseText);
 }

 inputSource = new InputSource( new StringReader( sw.toString() ) );
  //To get Response code:
 obj = xpath.evaluate("//responsens:ResponseCode/text()", inputSource, XPathConstants.STRING );
 if ( obj != null ) 
 { 
    String responseCode = obj.toString();
    System.out.println("Response code : " + responseCode);
 }
SomeDude
  • 13,876
  • 5
  • 21
  • 44
  • Hi thank you for your efforts I put your code into mine but I am getting this error: java.lang.RuntimeException: Unable to evaluate expression using this context at com.sun.org.apache.xpath.internal.axes.NodeSequence.setRoot(NodeSequence.java:266) at com.sun.org.apache.xpath.internal.axes.LocPathIterator.execute(LocPathIterator.java:214) at com.sun.org.apache.xpath.internal.XPath.execute(XPath.java:339) at com.sun.org.apache.xpath.internal.jaxp.XPathImpl.eval(XPathImpl.java:211) – Veljko Jun 27 '17 at 20:53
  • 1
    Is your xml string correct from sw.toString() ? I mean is it well formed xml? – SomeDude Jun 27 '17 at 20:59
  • Hi, line at which I am getting the exception is this one: Object obj = xpath.evaluate("//ResponseText/text()", is, XPathConstants.STRING ); – Veljko Jun 27 '17 at 21:02
  • I tested now and sw.toString() returns seem properly Mail Server will accept email3gmail-smtp-in.l.google.comtrue – Veljko Jun 27 '17 at 21:03
  • Mail Server will accept email 3 gmail-smtp-in.l.google.com true – Veljko Jun 27 '17 at 21:06
  • @for some reason it cannot reach ResponseText element in order to retrieve XML element value. Is it possible to debug this? Thanks in advance... I tried to put whole XML outut from sw.string in last two posts – Veljko Jun 27 '17 at 21:15
  • Can you please try in your class code @svasa? Thanks – Veljko Jun 27 '17 at 21:21
  • 1
    What is your InputSource ? is it `org.xml.sax.InputSource` ? You can see it in your imports. – SomeDude Jun 27 '17 at 21:24
  • it is import jdk.internal.org.xml.sax.InputSource; – Veljko Jun 27 '17 at 21:25
  • 1
    No you should have gotten the exception at : Object obj = xpath.evaluate("//ResponseCodet/text()", is, XPathConstants.STRING ); – SomeDude Jun 27 '17 at 21:35
  • I corrected and now I I have changed it now to import org.xml.sax.InputSource; But responseText string is empty. I have done it like this: Object obj = xpath.evaluate("//ResponseText/text()", is, XPathConstants.STRING ); System.out.println("5"); if ( obj != null ) { System.out.println("6"); responseText = obj.toString(); } System.out.println("response:"+responseText); – Veljko Jun 27 '17 at 21:35
  • And output is: 5 6 response: So you can see it writes SystemOutPrintln 5 and 6 and obj is !=null but reponseText varaible is empty. Do you have a clue why is that? Thanks – Veljko Jun 27 '17 at 21:37
  • thanks... but I think you have errors in the code: 1. you are uisng variable inputsource but above you have variable IS not inputsource 2. then inputSource = new InputSource( new StringReader( in ) ); this seems to be unfinished code --- what is IN??? can you please double check your code and edit it? Thanks – Veljko Jun 27 '17 at 21:47
  • 1
    Ok. Fixed. `is` should be `inputSource` and `in` should have been `sw.toString()` - updated. – SomeDude Jun 27 '17 at 21:48
  • what are you reffering with "responsens". I do not see that value (element) in the XML structure? – Veljko Jun 27 '17 at 21:50
  • 1
    It is a dummy namespace to refer to the default namespace. In your xml you have xmlns="http://ws.cdyne.com", The ResponseText falls under that namespace, so in xpath I refer that as responsens – SomeDude Jun 27 '17 at 21:52
  • It works!!! THANK YOU VERY MUCH!!!! I marked this as ANSWER! So to summarize you used just conversion of XML to XPATH without DOM in order to parse this, correct? Can I have one additional question? If I below the structure had additional multiple CHILDREN nodes for example: 1000 1001 how would I retrive those multiple elements INCIDENTID which has different values in different children elements? Can you write me that part also in comment? Thank you once again!!!!!!!!!! – Veljko Jun 27 '17 at 21:58
  • 1
    You need to use xpath : `//responsens:VerifyEmailResult/INCIDENT/INCIDENTID` and specify XPathConstants.NODESET in your evaluate( ) function instead of STRING.That will retrieve NodeList. Iterate over NodeList and call getTextContent() on each node. Go over xpath in java tutorial [here](http://www.journaldev.com/1194/java-xpath-example-tutorial) – SomeDude Jun 27 '17 at 22:01
  • Thanks. You used XPATH without DOM correct? For what purposes you needed getPrefix(String namespaceURI) and getPrefixes(String namespaceURI) overrriden methods? Thanks – Veljko Jun 27 '17 at 22:06
  • 1
    Even though I didn't mention anywhere DOM in my code, the xpath.evaluate(...) creates a DOM Parser first , parses the xml and then evaluates xpath. The getPrefix() methods are usually used in methods that are used to get qualified names like : `ns:nodeName` where `ns` is the namespace and `nodeName` is the name of the node e.g. `soap:Envelope` You don't need to worry about them in your example in xpath evaluation. I think I deserve more points on this answer :) – SomeDude Jun 28 '17 at 01:39