I would like to understand if it's possible to generate large XML files using XmlNode and Document classes in Batch apex?

Ideally, I would like the Dom.Document class variable to be stateful. However, this is not possible. As an attempted workaround, I have serialised the document into a string. This works in execute anonymous however it does not work in batch (System.SerializationException: Not Serializable: dom.XmlNode).

I have tried creating the file synchronously and also using @Future however both failed with CPU timeout beyond a small number of records. That is why I would like to create the XML document in small chunks within Salesforce governor limits.

Note that the code below has been simplified for illustration purposes.

Thanks in advance

public with sharing class ExampleBatchJob  implements Database.Batchable<sObject>, Database.Stateful {

Dom.Document doc = new DOM.Document();
Dom.XmlNode root = doc.createRootElement('AccountPerformanceSalesData', null, null);
String theDocAsString = doc.toXmlString();

public Database.QueryLocator start(Database.BatchableContext BC) {
    String query = 'SELECT Id FROM Account';
    return Database.getQueryLocator(query);

public void execute(Database.BatchableContext BC, List<sObject> scope) {

    Dom.Document doc2 = new DOM.Document();
    List<Account> accountList = scope;
    for (Account acc : accountList) {
        doc2.getRootElement().addChildElement('test', 'test', 'test');
    theDocAsString = doc2.toXmlString();

public void finish(Database.BatchableContext BC) {
  • 3
    Please use text instead of an image for your code. This makes it easier for users that use screen readers and people trying to answer your question.
    – sfdcfox
    Feb 7, 2022 at 19:43
  • Sure thing. Apologies I didn't know but makes total sense
    – Jay
    Feb 7, 2022 at 23:33

1 Answer 1


You can't serialize doc or root. Remove them from the class, and initialize theDocAsString in your start(Database.BatchableContext context) method.

public Database.QueryLocator start(Database.BatchableContext BC) {
  Dom.Document doc = new Dom.Document();
  theDocAsString = doc.toXmlString();
  return Database.getQueryLocator([SELECT Id FROM Account]);
  • Thanks for this @sfdcfox. You are the man, as always.
    – Jay
    Feb 7, 2022 at 23:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .