简体   繁体   中英

How to add another xml tag based on the content size using apache camel

Problem Statement:

I have flat file as input source which contains the text at first position of length varies from (0 - 80). If the length of the text is less than 40, I have to create one xml tag. If its greater than 40 I have to split it and append it to another xml tag. I was able to transform to xml but I need to implement the logic which will do the length check and generate the tags.

INPUT - Flat File with Pipe Delimited String

Hey how are u and hows ur life. long time no see. how u been|LIVE|002|6315115097|IN|US||POS REPLEN|N|QUEST NUTRITION LLC

ConverterRoute.java

@Data
public class ConverterRoute implements RoutesBuilder {

    String data;

    List<String> output = new ArrayList<>();
    JSONArray jsonArray = new JSONArray();


    public void addRoutesToCamelContext(CamelContext context) throws Exception {

        context.addRoutes(new RouteBuilder() {

            public void configure() {
                try {
                    DataFormat bindyFixed = new BindyCsvDataFormat(TEST.class);

                    XStreamDataFormat xStreamDataFormat = new XStreamDataFormat();
                    xStreamDataFormat.setAliases(Collections.singletonMap("TEST", TEST.class.getCanonicalName()));
                    xStreamDataFormat.setXstreamDriver(myCustomDriver);


                    from("direct:sendData").
                            split().tokenize(System.lineSeparator()).log("Line separator ${body}").
                            unmarshal(bindyFixed).log("Unmarshaling ${body}").
                            process(new AppendAttributesProcessor()).
                            marshal(xStreamDataFormat).
                            log("Finished Transformation ${body}").process(new Processor() {
                        @Override
                        public void process(Exchange exchange) throws Exception {
                            data = exchange.getIn().getBody(String.class);
                            data = data.replaceAll("[\n\r]", "");
                            output.add(data);

                            jsonArray.put(data);
                        }
                    });

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

}

AppendAttributesProcessor.java

public class AppendAttributesProcessor implements Processor {

    public void process(Exchange exchange) {
        TEST appt_inb_ifd = exchange.getIn().getBody(TEST.class);
        APPT_NOTE_SEG appt_note_seg = appt.getAPPT_NOTE_SEG();
        appt.setTRLR_NUM(appt.getAPPT_ID());

        String noteText = appt_note_seg.getNOTTXT();
        if (noteText.length() > 40) {
            System.out.println("Greater");
        } else {
            System.out.println("Lesser");
        }

        appt_note_seg.setNOTLIN("0001");
        appt_note_seg.setNOTTXT(noteText.substring(0, 40));
        appt.setAPPT_NOTE_SEG(appt_note_seg);
        exchange.getIn().setBody(appt_inb_ifd);
    }
}

OUTPUT I'm getting:

test.xml

<?xml version="1.0" encoding="utf-8" standalone="no"?>
    <TEST>
                <APPT_NOTE_SEG>
                    <SEGNAM>APPT_NOTE</SEGNAM>
                    <NOTLIN>0001</NOTLIN>
                    <NOTTXT>Hey how are u and hows ur life. long tim</NOTTXT>
                </APPT_NOTE_SEG>
</TEST>

EXPECTED OUTPUT:

test.xml

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<TEST>
            <APPT_NOTE_SEG>
                <SEGNAM>APPT_NOTE</SEGNAM>
                <NOTLIN>0001</NOTLIN>
                <NOTTXT>Hey how are u and hows ur life. long tim</NOTTXT>
            </APPT_NOTE_SEG>
            <APPT_NOTE_SEG>
                <SEGNAM>APPT_NOTE</SEGNAM>
                <NOTLIN>0002</NOTLIN>
                <NOTTXT>e no see. how u been</NOTTXT>
            </APPT_NOTE_SEG>
</TEST>

Edited:

I'm trying to use two object references in Author class which refers to same object. Based on the title length I would like to create the book object which generates the book xml tags. Here is the code which I'm using with the expected and current outputs which I'm getting.

Author.java

@Data
@CsvRecord(separator="," , skipField = true)
public class Author {

    @DataField(pos = 1)
    private String firstName;

    @DataField(pos = 2)
    private String lastName;

    @Link
    private Book book;

    @Link
    private Book bookOne;

    @DataField(pos = 5)
    private String Age;
}

Book.java

@Data
@Link
@CsvRecord(separator = ",")
public class Book {

    @DataField(pos = 3)
    private String title;

    @DataField(pos = 4)
    private String year;
}

Output Returing:

<?xml version="1.0" encoding="UTF-8"?>

<APPT_INB_IFD>
  <firstName>Claus</firstName>
  <lastName>Ibsen</lastName>
  <book>
    <title>Camel in Action 2</title>
    <year>2012</year>
  </book>
  <bookOne reference="../book"/>
  <Age>35</Age>
</APPT_INB_IFD>

Expected Output:

<?xml version="1.0" encoding="UTF-8"?>

<APPT_INB_IFD>
  <firstName>Claus</firstName>
  <lastName>Ibsen</lastName>
  <book>
    <title>Camel in Action 1</title>
    <year>2010</year>
  </book>
  <book>
    <title>Camel in Action 1</title>
    <year>2010</year>
  </book>
  <Age>35</Age>
</APPT_INB_IFD>

Could you reformat the expected output to wrap <APPT_NOTE_SEG> in an <APPT_NOTE_SEGS> tag? Then you could create a list of <APPT_NOTE_SEG> objects in your object you are using to do the marshal.

Otherwise you could have two <APPT_NOTE_SEG> objects in the class you are using to do the marshal and configure the first one with @XmlAttribute(required=true) and the second one with @XmlAttribute which will be ignored by the marshaller if it's null. Then just set the value as needed based on the logic you've already done.

Also not sure if you were just naming things to match the XML for this example, but just in case you can actually just create a pojo and annotate the elements with the XML naming you need:

@XmlRootElement(name = "test")
public class TestBean {
    @XmlAttribute(name = "desired_id_format")
    private String id;
    ...

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