Skip to main content
layout
Source Link
dexter
  • 121
  • 3

In Java parsing very large input is actually very easyI created a code generator designed to do even withoutsolve this particular problem (an early version was conceived in 2008). Basically each complexType has its Java POJO equivalent and handlers for the added complexity of cutting them upparticular type are activated when the context changes to that element. I used this approach for SEPA, transaction banking and for instance discogs (30GB). It scales perfectly because it givesYou can specify what elements you full control over how the processing is donewant to process at runtime, declaratively using a propeties file.

XML2J uses mapping of ComplexElementscomplexTypes to Java POJOs on the one hand, but lets you specify events you want to listen on. E.g.

In Java parsing very large input is actually very easy to do even without the added complexity of cutting them up. I used this approach for SEPA, transaction banking and for instance discogs (30GB). It scales perfectly because it gives you full control over how the processing is done.

XML2J uses mapping of ComplexElements to Java POJOs on the one hand, but lets you specify events you want to listen on. E.g.

I created a code generator designed to solve this particular problem (an early version was conceived in 2008). Basically each complexType has its Java POJO equivalent and handlers for the particular type are activated when the context changes to that element. I used this approach for SEPA, transaction banking and for instance discogs (30GB). You can specify what elements you want to process at runtime, declaratively using a propeties file.

XML2J uses mapping of complexTypes to Java POJOs on the one hand, but lets you specify events you want to listen on. E.g.

Source Link
dexter
  • 121
  • 3

In Java parsing very large input is actually very easy to do even without the added complexity of cutting them up. I used this approach for SEPA, transaction banking and for instance discogs (30GB). It scales perfectly because it gives you full control over how the processing is done.

XML2J uses mapping of ComplexElements to Java POJOs on the one hand, but lets you specify events you want to listen on. E.g.

account/@process = true
account/accounts/@process = true
account/accounts/@detach = true

The essence is in the third line. The detach makes sure individual accounts are not added to the accounts list. So it won't overflow.

class AccountType {
    private List<AccountType> accounts = new ArrayList<>();

    public void addAccount(AccountType tAccount) {
        accounts.add(tAccount);
    }
    // etc.
};

In your code you need to implement the process method (by default the code generator generates an empty method:

class AccountsProcessor implements MessageProcessor {
    static private Logger logger = LoggerFactory.getLogger(AccountsProcessor.class);

    // assuming Spring data persistency here
    final String path = new ClassPathResource("spring-config.xml").getPath();
    ClassPathXmlApplicationContext context = new   ClassPathXmlApplicationContext(path);
    AccountsTypeRepo repo = context.getBean(AccountsTypeRepo.class);


    @Override
    public void process(XMLEvent evt, ComplexDataType data)
        throws ProcessorException {

        if (evt == XMLEvent.END) {
            if( data instanceof AccountType) {
                process((AccountType)data);
            }
        }
    }

    private void process(AccountType data) {
        if (logger.isInfoEnabled()) {
            // do some logging
        }
        repo.save(data);
    }
}   

Note that XMLEvent.END marks the closing tag of an element. So, when you are processing it, it is complete. If you have to relate it (using a FK) to its parent object in the database, you could process the XMLEvent.BEGIN for the parent, create a placeholder in the database and use its key to store with each of its children. In the final XMLEvent.END you would then update the parent.

Note that the code generator generates everything you need. You just have to implement that method and of course the DB glue code.

There are samples to get you started. The code generator even generates your POM files, so you can immediately after generation build your project.

The default process method is like this:

@Override
public void process(XMLEvent evt, ComplexDataType data)
    throws ProcessorException {


/*
 *  TODO Auto-generated method stub implement your own handling here.
 *  Use the runtime configuration file to determine which events are to be sent to the processor.
 */ 
        
    if (evt == XMLEvent.END) {
        data.print( ConsoleWriter.out );
    }
}

Downloads:

First mvn clean install the core (it has to be in the local maven repo), then the generator. And don't forget to set up the environment variable XML2J_HOME as per directions in the usermanual.