java - 如何使用 apache Camel 根据内容大小添加另一个 xml 标签

标签 java xml apache-camel spring-camel bindy

问题陈述:

我有平面文件作为输入源,其中包含长度从(0 - 80)变化的第一个位置的文本。如果文本长度小于 40,我必须创建一个 xml 标签。如果它大于 40,我必须将其拆分并将其附加到另一个 xml 标记。我能够转换为 xml,但我需要实现进行长度检查并生成标签的逻辑。

输入 - 带有管道分隔字符串的平面文件

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);
    }
}

我得到的输出:

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>

预期输出:

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>

已编辑:

我试图在 Author 类中使用两个引用同一对象的对象引用。根据标题长度,我想创建生成图书 xml 标签的图书对象。这是我正在使用的代码以及我得到的预期和当前输出。

作者.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;
}

输出返回:

<?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>

预期输出:

<?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>

最佳答案

您能否重新格式化预期输出以换行 <APPT_NOTE_SEG><APPT_NOTE_SEGS>标签?然后你可以创建一个 <APPT_NOTE_SEG> 的列表您用于执行编码的对象中的对象。

否则你可能有两个 <APPT_NOTE_SEG>您用来执行编码(marshal)处理的类中的对象并使用 @XmlAttribute(required=true) 配置第一个对象第二个是 @XmlAttribute如果它为空,则编码器将忽略它。然后根据您已经完成的逻辑根据需要设置值。

还不确定您是否只是命名事物以匹配此示例的 XML,但以防万一您实际上可以创建一个 pojo 并使用您需要的 XML 命名来注释元素:

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

关于java - 如何使用 apache Camel 根据内容大小添加另一个 xml 标签,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59556669/

相关文章:

java - kafka涉及微服务架构时如何实现契约测试?

java - 使用 Hibernate 4's Integrator pattern and Spring' 的依赖注入(inject)

xml - 如何使用 cURL 发布 XML 文件?

sql - 如何在子查询中使用 FOR XML?

java - 让 spring 上下文变量指向 webapp 中的实际外部上下文

java - 如何仅使用 apache camel 从 http 读取一次 csv 文件?

java - 如何在Camel 3.x中获取RouteDefinition(从2.x迁移到3.x)

java - 为什么 AsyncTask 在添加新数据后不自动更新 GraphView?

java - 如何以编程方式从本地java项目中查找svn目录

java - 获取多个同名的 XML 元素 JAXB