Adding custom XML nodes and attributes to the DDSP of a report

Sometimes we would like to add custom XML nodes and attributes to the already existing DDSP, without necessarily creating an entirely new XML structure (for that, you can check out this forum post).

We’re going to be showing how to achieve adding a couple of nodes and attributes like in the following screenshot:

Here’s a working example class that adds custom nodes and attributes to the DDSP of the CustCollectionJour.Report report via inheritance:

class DocCustCollectionJourReportWithCustomXMLStructureDSP extends DocCustCollectionJourReportDSP
{
    public ClassDescription description()
    {
        return 'Collection letter note with custom XML structure DSP';
    }

    protected void generateXmlDataSource(DocXmlRecordBuilder _recordBuilder)
    {
        // If we want to position the XML nodes AFTER the nodes from the DSP, we call super() BEFORE our logic.
        //super(_recordBuilder);

        // Position XML writer to ReportData node.
        _recordBuilder.goToTopRecord();

        // Create a new node inside the ReportData node, since our cursor is currently positioned on the top ReportData node.
        _recordBuilder.addCalculatedRecord('CustomXMLNode', 'Custom XML Node');
        
        // Create a new node inside the CustomXMLNode from the previous step, since when a node is created via the addCalculatedRecord() method, the cursor is automatically positioned to that node.
        _recordBuilder.addCalculatedRecord('AnotherCustomXMLNode', 'Another Custom XML Node');

        // Create 3 nodes inside the AnotherCustomXMLNode node.
        for (int i = 0; i < 3; i++)
        {
            DocXmlRecord currentRecord = _recordBuilder.addCalculatedRecord('CustomLoopedXMLNode', 'Custom looped XML node');

            // Create the attribute CustomValue for each CustomLoopedXMLNode node.
            currentRecord.addCalculatedField('CustomValue', i+1, 'Custom value');
        }

        // If we want to navigate back to any previous node, we can do so by searching for the node by name from the top node.
        DocXmlRecord customXmlNodeRecord = _recordBuilder.topRecord().getFirstChildRecordByName('CustomXMLNode');

        // Now we can add additional attributes or nodes as needed.
        customXmlNodeRecord.addCalculatedField('CustomValue', 'This value was added after!', 'Custom Value');

        // If we want to position the XML nodes BEFORE the nodes from the DSP, we call super() AFTER our logic.
        super(_recordBuilder);
    }
}

We recommend using inheritance when customizing Docentric DSP classes, because that way you can choose to fall back to the original report specific DSP class in case an error occurs (don’t forget to pick your new custom DSP class when testing!):