简体   繁体   中英

Parse XML Namespaces (server response), in JAVA

I want to show the response that the server sends me, but at the time of parsing it shows me the empty string. I've tried parsing the server response as shown in other tutorials, but it does not work. Does anyone know I'm doing wrong?

JAVA CODE

import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.w3c.dom.Document;
import freemarker.template.Configuration;
import freemarker.template.Template;
public class ClienteSoap {
    public static void main(String[] args) {
        HttpClient httpClient = null;   

          try {
            Configuration cfg = new Configuration();

            // Cargar plantilla
            Template template = cfg.getTemplate("src/main/resources/templates/template.ftl");

            // Modelo de datos
            Map<String, Object> data = new HashMap<String, Object>();
            data.put("token", "u757Ric6542ytu6Ricgtr0");
            data.put("branch", "1");
            data.put("app", "S-04600");
            data.put("folio", "4345Ric67");
            data.put("temp", "False");


            // Crear mensaje SOAP HTTP
            StringWriter out = new StringWriter();
            template.process(data, out);
            String strRequest = out.getBuffer().toString();
            System.out.println(strRequest);

            // Crear la llamada al servidor
            httpClient = new DefaultHttpClient();
            HttpPost postRequest = new
            HttpPost("http://127.0.0.1:30005/PCIServicioConciliadorCore-web"); //direccion de la pagina
            StringEntity input = new StringEntity(strRequest);
            input.setContentType("text/xml");
            postRequest.setEntity(input);

            // Tratar respuesta del servidor
            HttpResponse response = httpClient.execute(postRequest);
            if (response.getStatusLine().getStatusCode() != 200) {
                throw new RuntimeException("Error : Código de error HTTP : " + response.getStatusLine().getStatusCode());
            }

            //Obtener información de la respuesta
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            System.out.println(factory);
            Document XMLDoc = factory.newDocumentBuilder().parse(response.getEntity().getContent());
            XPath xpath = XPathFactory.newInstance().newXPath();
            XPathExpression expr = xpath.compile("/AddToken2DBResponseType/Token");
            String result = String.class.cast(expr.evaluate(XMLDoc, XPathConstants.STRING));
            System.out.println("\nEl resultado es: " + result.length());
        }catch (Exception e) {
            e.printStackTrace();
        } finally {
            // Cierre de la conexión
            if (httpClient != null) httpClient.getConnectionManager().shutdown();
        }
    }
}

WSDL RESPONSE

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body>
      <ns2:AddToken2DBResponse xmlns:ns2="http://www.example.com/edit/example">
         <ns2:Token>u757Ric6542ytu6Ricgtr0</ns2:Token>
         <ns2:HandlerError>
            <ns2:statusCode>true</ns2:statusCode>
            <ns2:errorList>
               <ns2:error>
                  <ns2:code>OK</ns2:code>
                  <ns2:origin>JBOSS</ns2:origin>
                  <ns2:userMessage>Primer registro insertado</ns2:userMessage>
                  <ns2:developerMessage>Primer registro insertado</ns2:developerMessage>
               </ns2:error>
            </ns2:errorList>
         </ns2:HandlerError>
      </ns2:AddToken2DBResponse>
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

I appreciate your help

Your XPath expression is wrong, if it starts with a single / it means that the element should be a/the root element (so obviously it will not find anything as the root element is SOAP-ENV:Envelope ). So far it should be //AddToken2DBResponseType/Token .

Second issue is the namespace; you have two options (i am aware of):

  • parse it namespace aware and rewrite the xpath to be by tolerant towards the namespace.
  • parse it namespace unaware and use the namespace prefix in the xpath.

The second option is quite unstable so here is the first:

 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
 factory.setNamespaceAware(true);
 // ...
 XPathExpression expr = xpath.compile("//*[local-name='AddToken2DBResponseType']/*[local-name='Token']");

//*[local-name='abc'] Means any element that has a local-name (name without namespace) of abc (exactly what you want/need).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM