IBM webMethods Hybrid Integration

IBM webMethods Hybrid Integration

Join this online group to communicate across IBM product users and experts by sharing advice and best practices with peers and staying up to date regarding product enhancements.

 View Only
  • 1.  Java service which extracts the value of a field at runtime

    Posted Tue July 31, 2012 03:32 PM

    Hi,

    I need to build a java service which extracts the value of a field at runtime. The path of the field in the canonical and the canonical document itself should be given as input.
    Eg:
    fromDoc consists of sub documents within it, in a hierarchy, ie.
    fromDoc/Data/Parameters/outDate

    • fromDoc
      [LIST]
    • Data
      [LIST]
    • Parameters
      [LIST]
    • outDate(string)
      [/LIST]
      [/LIST]
      [/LIST]

    For inStringValues I give the input as ‘fromDoc/Data/Parameters/outDate’

    the output should return the value of the variable ‘fromDoc/Data/Parameters/outDate’ at run time.

    I have a code which implements this with the key value pair logic.

    IDataCursor pipelineCursor = pipeline.getCursor();
    // fromDoc
    IData     fromDoc = IDataUtil.getIData( pipelineCursor, "fromDoc" );
    String[] inStringValues = IDataUtil.getStringArray( pipelineCursor, "inStringValues" );
    if ( fromDoc == null)
    {
    return;
    }
    pipelineCursor.destroy();
    int len = inStringValues.length;
    String[] outStrings = new String[len];
    IDataCursor fromCursor = fromDoc.getCursor();
    boolean hasData = false;
    while( fromCursor.next() )
    {
    for(int i=0;i<len;i++)
    {
    String key = fromCursor.getKey();
    String val = fromCursor.getValue().toString();
    if(key.equals(inStringValues[i]))
    {
    outStrings[i]=key + "," + val;
    }
    }
    }
    fromCursor.destroy();
    IDataCursor pipelineCursor_1 = pipeline.getCursor();
    IDataUtil.put( pipelineCursor_1, "outStrings", outStrings );
    pipelineCursor_1.destroy();
    
    

    Please let me know how I can modify this code to implement the above mentioned logic?
    Or let me know if anyone has such an existing service with you.


    #Flow-and-Java-services
    #webMethods
    #Integration-Server-and-ESB


  • 2.  RE: Java service which extracts the value of a field at runtime

    Posted Tue July 31, 2012 06:10 PM

    Use the XPath API to achieve this. Convert the doc to an XML string and then use an xpath to get the value for a particular field in the xml.

    Inputs:
    xpathExpression
    xmlString

    Outputs:
    fieldValue
    error

    Imports:

    import org.w3c.dom.*;
    import org.xml.sax.SAXException;
    import javax.xml.parsers.*;
    import javax.xml.xpath.*;

    Java Service

            IDataCursor pipelineCursor = pipeline.getCursor();
    String    xpathExpression = IDataUtil.getString( pipelineCursor, "xpathExpression" );
    String    xmlString = IDataUtil.getString( pipelineCursor, "xmlString" );
    pipelineCursor.destroy();
    
    
    DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
    domFactory.setNamespaceAware(true);
    
    try {
    InputStream is=new ByteArrayInputStream(xmlString.getBytes("UTF-8"));
    DocumentBuilder builder = domFactory.newDocumentBuilder();
    Document doc = builder.parse(is);
    XPathFactory factory = XPathFactory.newInstance();
    XPath xpath = factory.newXPath();
    XPathExpression expr= xpath.compile(xpathExpression);
    
    //refine this part of the code
    Object result = expr.evaluate(doc, XPathConstants.NODESET);
    NodeList nodes = (NodeList) result;
    for (int i = 0; i < nodes.getLength(); i++) {
    IDataUtil.put(pipelineCursor, "fieldValue", nodes.item(i).getNodeValue());
    }
    //end
    } catch (ParserConfigurationException e) {
    e.printStackTrace();
    IDataUtil.put(pipelineCursor, "error", e);
    } catch (SAXException e) {
    e.printStackTrace();
    IDataUtil.put(pipelineCursor, "error", e);
    } catch (IOException e) {
    e.printStackTrace();
    IDataUtil.put(pipelineCursor, "error", e);
    } catch (XPathExpressionException e) {
    e.printStackTrace();
    IDataUtil.put(pipelineCursor, "error", e);
    }
    pipelineCursor.destroy();

    Sample input:

    /inputDoc/infoDoc/field1/text()
    
    <?xml version="1.0"?>
    <inputDoc>
    <infoDoc>
    <field1>abc</field1>
    <field2>123</field2>
    </infoDoc>
    </inputDoc>

    Output:
    abc


    #webMethods
    #Integration-Server-and-ESB
    #Flow-and-Java-services


  • 3.  RE: Java service which extracts the value of a field at runtime

    Posted Tue July 31, 2012 06:17 PM

    Alternatives to consider:

    • Just map the value from the IS document.
    • Use pub.xml:queryXMLNode to query the XML node using XQL (assuming the XML node is still available or can be made available)

    #Flow-and-Java-services
    #Integration-Server-and-ESB
    #webMethods


  • 4.  RE: Java service which extracts the value of a field at runtime

    Posted Wed August 01, 2012 12:14 AM

    @akki_84: Sounds to me like, as we say in german, “shooting sparrows with cannons”.

    I recommend to send in a single string giving the path name, eg something like “doc/subDocLevel2/Level3/Level4/field” and a Document. get the iData for the Pipeline and split the string into components using Java’s String.split(“/”) to get an array of path components. use all but the last to iterate down to the final document and then get the value that it is pointing at.

    IDataCursor now = pipeline.getCursor();
    String[] components = IDataUtil.getString(now, "path").split("/");
    for (int i=0; i < components.length-1) {[INDENT]IDataCursor next = IDataUtil.getIData(now, components[i]).getCursor();
    now.destroy();
    now = next;[/INDENT]
    }
    String field = now.GetString(components[components.lenght-1]);
    now.destroy();
    now = pipeline.getCursor();
    IDataUtil.putString(now, "result", field);
    now.destroy();

    Errorhandling and checking for invalid input (like // in a string or strings starting with / may be added as an exercise.

    Thomas


    #webMethods
    #Flow-and-Java-services
    #Integration-Server-and-ESB


  • 5.  RE: Java service which extracts the value of a field at runtime

    Posted Wed August 01, 2012 02:59 PM


    If that’s what it takes to get the job done, so be it :slight_smile:

    I have a question about your solution though, if there is an array in the IData doc how will the fields under that structure be extracted?

    Cheers,
    Akshith


    #Flow-and-Java-services
    #Integration-Server-and-ESB
    #webMethods


  • 6.  RE: Java service which extracts the value of a field at runtime

    Posted Wed August 01, 2012 03:31 PM

    With extra code. Then you either get an IData or an IData. If you want to deal with arrays too, my recommendation would require extension to understand and handle a syntax like doc/subDoc/subSubDoc[42]/field or whatever is convenient.

    something along the lines of

    [FONT=courier new]Pattern p = Pattern.compile(".*\\[[0-9]+\\]"); // place outside the loop, need to construct pattern to look for only once[/font]
    
    [FONT=courier new]Matcher m = p.matcher(components[i]); // put into the loop
    if (m.find()) {[/font][INDENT][FONT=courier new]// handle array case. error handling left as exercise :)
    next = IDataUtils.getIDataArray(now, m.group(0))[Integer.parseInt(m.group(1))].getCursor();[/font][/INDENT]
    [FONT=courier new]} else {
    [/font][INDENT][FONT=courier new]// as before[/font][/INDENT]
    [FONT=courier new]}
    [/font]

    shouldnt be too much work to get this one right for a java person.

    Thomas


    #webMethods
    #Flow-and-Java-services
    #Integration-Server-and-ESB


  • 7.  RE: Java service which extracts the value of a field at runtime

    Posted Wed August 01, 2012 04:10 PM

    Yup, that should do it. Good thread, we learn something new everyday!

    I wonder which of the solutions would fare better under a load test though.

    Cheers,
    Akshith


    #Integration-Server-and-ESB
    #Flow-and-Java-services
    #webMethods


  • 8.  RE: Java service which extracts the value of a field at runtime

    Posted Wed August 01, 2012 04:22 PM

    MINE! :slight_smile:

    Parsing XML is overkill for the task. Keep things simple. But not too simple.

    Thomas


    #Integration-Server-and-ESB
    #Flow-and-Java-services
    #webMethods