пятница, 18 октября 2013 г.

CDATA wraper feature

Казалось бы просто веб-сервис: на входе и выходе строка:
    public String processByJavaAdapter(String data, FreeMarkerVars[] reportContext, String className) throws Exception
    {
     ..
    }
Если строка XML, то возвращается обертка в CDATA:
<ns2:processByJavaAdapterResponse xmlns:ns2="http://wsi.reg.sitronics.com/">
      </ns2:processByJavaAdapterResponse>
         <return><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
         <error>
   <faultcode>Нет связи с сервером</faultcode>
   <fault></fault>
   </error>]]></return>


А вот не всегда.
Иногда ответ приходит таким:

<ns2:processByJavaAdapterResponse xmlns:ns2="http://wsi.reg.sitronics.com/">
         <return>&lt;?xml version="1.0" encoding="UTF-8"?>
  &lt;faultcode>Нет связи с сервером&lt;/faultcode></return>
      </ns2:processByJavaAdapterResponse>


И это не баг, а фича :-)
Иногда веб-сервису кажется что такой способ обертки XML более лучший.

четверг, 3 октября 2013 г.

Поменять значение в XML

Требуется поменять значение, спрятанное глубоко в XML.

<smev:RequestIdRef>{219F416E-4DB7-43DA-AFED-2EFFDD67C32A}</smev:RequestIdRef>



import org.apache.xpath.XPathAPI;

...



String respBody = "....";// XML
Element root = getXmlRoot(respBody);
Node requestIdRefNode = getXPath(root, "//*[local-name() = 'RequestIdRef']");
requestIdRefNode.setTextContent("New value");

public static final Element getXmlRoot(String xmlData) throws Exception
{
        // logger.info("Trying get root from: " + xmlData);
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        factory.setNamespaceAware(true);
        DocumentBuilder builder = factory.newDocumentBuilder();
        return builder.parse(new InputSource(new StringReader(xmlData))).getDocumentElement();
}

public static final Node getXPath(Element xmlData, String path) throws Exception

{
       Node nodes = null;    
       nodes = XPathAPI.selectSingleNode(xmlData,
                                 String.format("%s", path));
       return nodes;
 } 
Альтернативный способ, без использование XPathAPI:
    public static Document getXMLDocument(String xmlSource) throws Exception
    {
        DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = domFactory.newDocumentBuilder();
        return builder.parse(new InputSource(new StringReader(xmlSource)));
    }
 
    public static Node getXMLTagContent(Document document, String nodeExpression) throws XPathExpressionException
    {
        Node node = null;
        XPathFactory factory = XPathFactory.newInstance();
        XPath xpath = factory.newXPath();
        XPathExpression expression = xpath.compile(nodeExpression);
        if (document != null)
            node = (Node) expression.evaluate(document, XPathConstants.NODE);
        return node;
    }