0
votes

-----> For the solution see the end of this question vvvvvvv

I'm trying to edit XML-files with Mule but I can't get it running.

The flow I'm trying to get working is:

Flow

and the code in the java-transform I've written is:

package se.xcorp.mulecomponents;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;


import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.nio.channels.FileChannel;

import org.mule.api.MuleMessage;
import org.mule.api.transformer.TransformerException;
import org.mule.api.transport.PropertyScope;
import org.mule.config.i18n.MessageFactory;
import org.mule.transformer.AbstractMessageTransformer;

public class checkXML extends AbstractMessageTransformer
{    
@Override
public Object transformMessage(MuleMessage message, String outputEncoding)
        throws TransformerException {


      try {

            SAXBuilder builder = new SAXBuilder();
//              

            Document doc = (Document) builder.build((java.io.InputStream)message);
            Element rootNode = doc.getRootElement();

            // update staff id attribute
            String workpl = rootNode.getChildText("Arb_plats_ID");
            if (workpl==""){
                System.out.println("Empty!!!!");
                rootNode.getChild("Arb_plats_ID").setText("0");
            } else {
                System.out.println(workpl);
            }


            XMLOutputter xmlOutput = new XMLOutputter();

            // display nice nice
            xmlOutput.setFormat(Format.getPrettyFormat());
            xmlOutput.output(doc, new FileWriter("c:\\JAVATEST\\DATAUT\\1.xml"));

            // xmlOutput.output(doc, System.out);

            System.out.println("File updated!");
          } catch (IOException io) {
            io.printStackTrace();
          } catch (JDOMException e) {
            e.printStackTrace();
          }

    return null;
}


}

And the exception is:

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + Started app 'xmlchecknedit' + ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ INFO 2013-11-07 16:24:27,943 [[xmlchecknedit].connector.file.mule.default.receiver.01] org.mule.transport.file.FileMessageReceiver: Lock obtained on file: C:\JAVATEST\DATAIN\40171700_100470.xml ERROR 2013-11-07 16:24:28,049 [[xmlchecknedit].XMLcheckneditFlow2.stage1.02] org.mule.exception.DefaultMessagingExceptionStrategy:


Message : org.mule.DefaultMuleMessage cannot be cast to java.io.InputStream (java.lang.ClassCastException). Message payload is of type: byte[]

Code : MULE_ERROR--2

Exception stack is: 1. org.mule.DefaultMuleMessage cannot be cast to java.io.InputStream (java.lang.ClassCastException) se.hansandersson.mulecomponents.checkXML:36 (null) 2. org.mule.DefaultMuleMessage cannot be cast to java.io.InputStream (java.lang.ClassCastException). Message payload is of type: byte[] (org.mule.api.transformer.TransformerMessagingException)

org.mule.transformer.AbstractTransformer:139 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transformer/TransformerMessagingException.html)

Root Exception stack trace: java.lang.ClassCastException: org.mule.DefaultMuleMessage cannot be cast to java.io.InputStream at se.hansandersson.mulecomponents.checkXML.transformMessage(checkXML.java:36) at org.mule.transformer.AbstractMessageTransformer.transform(AbstractMessageTransformer.java:145) at org.mule.transformer.AbstractMessageTransformer.transform(AbstractMessageTransformer.java:93) + 3 more (set debug level logging or '-Dmule.verbose.exceptions=true' for everything)


I Appreciate any input to get this working!

I still can't get this to work, What I want to do is to do what fhe following Java-code does but put this into a mule flow to take care of the file management. The Java checks if an XML-element-child is empty and if it is then its updated to "0".

This java-code works like I wan't it to but I can't convert it into the mule-flow. Please help! /Claes

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

public class ModifyXMLFile {
public static void main(String[] args) {

  try {

    SAXBuilder builder = new SAXBuilder();
    File xmlFile = new File("c:\\JAVATEST\\DATAIN\\1.xml");

    Document doc = (Document) builder.build(xmlFile);
    Element rootNode = doc.getRootElement();

    // update staff id attribute
    String workpl = rootNode.getChildText("Arb_plats_ID");
    if (workpl==""){
        System.out.println("Empty!!!!");
        rootNode.getChild("Arb_plats_ID").setText("0");
    } else {
        System.out.println(workpl);
    }


    XMLOutputter xmlOutput = new XMLOutputter();

    // display nice nice
    xmlOutput.setFormat(Format.getPrettyFormat());
    xmlOutput.output(doc, new FileWriter("c:\\JAVATEST\\DATAUT\\1.xml"));

    // xmlOutput.output(doc, System.out);

    System.out.println("File updated!");
  } catch (IOException io) {
    io.printStackTrace();
  } catch (JDOMException e) {
    e.printStackTrace();
  }
}
}

THE SOLUTION!!!!

Here's the Mule XML and the Java Class that together checks if an XML-element is empty and if it is assigns 0 to it and then passes it back to the flow for being saved.

MULE XML-----------------------------------

    <flow name="XMLcheckneditFlow2" doc:name="XMLcheckneditFlow2">
    <file:inbound-endpoint path="C:\JAVATEST\DATAIN" responseTimeout="10000"    doc:name="File">

    </file:inbound-endpoint>
     <byte-array-to-string-transformer doc:name="Byte Array to String"></byte-array-to-string-transformer>
    <custom-transformer class="se.hansandersson.mulecomponents.checkXML" doc:name="Java"/>
    <file:outbound-endpoint path="C:\JAVATEST\DATAUT" responseTimeout="10000" doc:name="File"/>
</flow>
</mule>

THE JAVA CODE-------------------------------------------

public class checkXML extends AbstractMessageTransformer
{   
@Override
public Object transformMessage(MuleMessage message, String outputEncoding)
        throws TransformerException {
    String returnstring="";


    try {
        String  xmlString = (String)message.getPayload();
        SAXBuilder saxBuilder = new SAXBuilder();
                InputStream stream = new ByteArrayInputStream(xmlString.getBytes("UTF-8"));
                Document doc = saxBuilder.build(stream);

            Element rootNode = doc.getRootElement();

            // update staff id attribute
            String workpl = rootNode.getChildText("Arb_plats_ID");
            if (workpl==""){
                System.out.println("Empty!!!!");
                rootNode.getChild("Arb_plats_ID").setText("0");
            } else {
                System.out.println(workpl);
            }


            XMLOutputter xmlOutput = new XMLOutputter();

            // display nice nice

            returnstring = xmlOutput.outputString(doc);


            System.out.println("File updated!");


          } catch (IOException io) {
            io.printStackTrace();
          } catch (JDOMException e) {
            e.printStackTrace();
          }

    return returnstring;
}
1

1 Answers

1
votes

Try this way.

<file:inbound-endpoint path=""  ......  >
     <byte-array-to-string-transformer></byte-array-to-string-transformer>      
</file:inbound-endpoint>

 <component  ....  java component>

This way you will have the incoming file as XMLStreamReader into your Java component where the SAXParser can be applied to read and transform it.

String  xmlString = (String)message.getPayload();
SAXBuilder saxBuilder = new SAXBuilder();
        InputStream stream = new ByteArrayInputStream(xmlString.getBytes("UTF-8"));
        Document doc = saxBuilder.build(stream);

The file will be available as String in the Java Component. Which you can transformer using parsers.

Hope this helps.