0

I'm trying to split an xml input document for every 5 elements. Using the below sample input doc, I would like to split it for every 5 JournalEntry elements. I've also provided a sample output document.

XML Input

    <?xml version="1.0" encoding="UTF-8"?>
    <JournalFileData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:js="urn:com.journal/JournalSource" js:Add="false">
    <AccountingData>
        <Locked>0</Locked>
        <Company js:type="Organization_Reference_ID">Some Company</Company>
        <Currency>USD</Currency>
        <Ledger>ACTUALS</Ledger>
        <Date>12-15-2021</Date>
        <Journal>Manual</Journal>
        <JournalEntry>
            <LineCompany js:type="Company">Widget Company</LineCompany>
            <LedgerAccount js:type="Ledger_Account_ID">1000</LedgerAccount>
            <CreditAmount>100</CreditAmount>
            <Currency>USD</Currency>
        </JournalEntry>
        <JournalEntry>
            <LineCompany js:type="Organization">Global Company</LineCompany>
            <LedgerAccount js:type="Ledger_Account_ID">9999</LedgerAccount>
            <DebitAmount>100</DebitAmount>
            <Currency>USD</Currency>
        </JournalEntry>
        <JournalEntry>
            <LineCompany js:type="Company">JAG Company</LineCompany>
            <LedgerAccount js:type="Ledger_Account_ID">1000</LedgerAccount>
            <DebitAmount>100</DebitAmount>
            <Currency>USD</Currency>
        </JournalEntry>
        <JournalEntry>
            <LineCompany js:type="Organization">Resource Company</LineCompany>
            <LedgerAccount js:type="Ledger_Account_ID">9999</LedgerAccount>
            <DebitAmount>100</DebitAmount>
            <Currency>USD</Currency>
        </JournalEntry>
        <JournalEntry>
            <LineCompany js:type="Organization">Supply Company</LineCompany>
            <LedgerAccount js:type="Ledger_Account_ID">9999</LedgerAccount>
            <DebitAmount>100</DebitAmount>
            <Currency>USD</Currency>
        </JournalEntry>
        <JournalEntry>
            <LineCompany js:type="Company">Plain Company</LineCompany>
            <LedgerAccount js:type="Ledger_Account_ID">1000</LedgerAccount>
            <DebitAmount>100</DebitAmount>
            <Currency>USD</Currency>
        </JournalEntry>
        <JournalEntry>
            <LineCompany js:type="Organization">Gnome Company</LineCompany>
            <LedgerAccount js:type="Ledger_Account_ID">9999</LedgerAccount>
            <DebitAmount>100</DebitAmount>
            <Currency>USD</Currency>
        </JournalEntry>
    </AccountingData>
</JournalFileData>

XML Output

    <?xml version="1.0" encoding="UTF-8"?>
    <FileList>
    <File>
        <JournalFileData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:js="urn:com.journal/JournalSource" js:Add="false">
            <AccountingData>
                <Locked>0</Locked>
                <Company js:type="Organization_Reference_ID">Some Company</Company>
                <Currency>USD</Currency>
                <Ledger>ACTUALS</Ledger>
                <Date>12-15-2021</Date>
                <Journal>Manual</Journal>
                <JournalEntry>
                    <LineCompany js:type="Company">Widget Company</LineCompany>
                    <LedgerAccount js:type="Ledger_Account_ID">1000</LedgerAccount>
                    <CreditAmount>100</CreditAmount>
                    <Currency>USD</Currency>
                </JournalEntry>
                <JournalEntry>
                    <LineCompany js:type="Organization">Global Company</LineCompany>
                    <LedgerAccount js:type="Ledger_Account_ID">9999</LedgerAccount>
                    <DebitAmount>100</DebitAmount>
                    <Currency>USD</Currency>
                </JournalEntry>
                <JournalEntry>
                    <LineCompany js:type="Company">JAG Company</LineCompany>
                    <LedgerAccount js:type="Ledger_Account_ID">1000</LedgerAccount>
                    <DebitAmount>100</DebitAmount>
                    <Currency>USD</Currency>
                </JournalEntry>
                <JournalEntry>
                    <LineCompany js:type="Organization">Resource Company</LineCompany>
                    <LedgerAccount js:type="Ledger_Account_ID">9999</LedgerAccount>
                    <DebitAmount>100</DebitAmount>
                    <Currency>USD</Currency>
                </JournalEntry>
            </AccountingData>
        </JournalFileData>
    </File>
    <File>
        <JournalFileData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:js="urn:com.journal/JournalSource" js:Add="false">
            <AccountingData>
                <Locked>0</Locked>
                <Company js:type="Organization_Reference_ID">Some Company</Company>
                <Currency>USD</Currency>
                <Ledger>ACTUALS</Ledger>
                <Date>12-15-2021</Date>
                <Journal>Manual</Journal>
                <JournalEntry>
                    <LineCompany js:type="Company">Plain Company</LineCompany>
                    <LedgerAccount js:type="Ledger_Account_ID">1000</LedgerAccount>
                    <DebitAmount>100</DebitAmount>
                    <Currency>USD</Currency>
                </JournalEntry>
                <JournalEntry>
                    <LineCompany js:type="Organization">Gnome Company</LineCompany>
                    <LedgerAccount js:type="Ledger_Account_ID">9999</LedgerAccount>
                    <DebitAmount>100</DebitAmount>
                    <Currency>USD</Currency>
                </JournalEntry>
            </AccountingData>
        </JournalFileData>
    </File>
    </FileList>

Here is my last xslt attempt (Please excuse any typos. I had to type this out). I've had various results but none have gotten me the output I need. I'm having trouble finding the correct syntax to get the format outlined in the xml output. Also having trouble trying to copy the child nodes for each AccountingData node. I don't work with xslt frequent enough and still consider myself a novice so any help is appreciated. This is just my last try.:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:js="urn:com.journal/JournalSource" js:Add="false"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs">

    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="JournalFileData/AccountingData">
        <FileList>
            <xsl:copy>
                <xsl:for-each-group select="JournalEntry" group-adjacent="(position() -1) idiv 5">
                    <File>
                        <JournalFileData xmlns:js="urn:com.journal/JournalSource" js:Add="false">
                            <AccountingData>
                                <xsl:copy-of select="current-group()"/>
                            </AccountingData>
                        </JournalFileData>
                    </File>
                </xsl:for-each-group>
            </xsl:copy>
        </FileList>
    </xsl:template>
    
</xsl:stylesheet>
  • Does this answer your question? [XSLT - Split large XML into multiple files based on criteria](https://stackoverflow.com/questions/63604903/xslt-split-large-xml-into-multiple-files-based-on-criteria) – Dijkgraaf Nov 16 '22 at 22:24
  • The shown output is a single document, if you want multiple, as your text and subject suggests, you will need to throw in `xsl:result-document` inside of each group you process and there create any content you need/want, not outside. – Martin Honnen Nov 16 '22 at 22:34
  • Hi @Dijkgraaf, thank you for your response and suggestion. I did see the article you referenced. I did try to implement a similar solution earlier on but I'm having issues with getting the correct syntax. I don't work with XSLT that often and am still a bit of a novice – user6353351 Nov 16 '22 at 22:39
  • Hi @MartinHonnen, there is a process that will handle splitting the file. I just need to get it into the correct format. I could have worded my question a little better. My apologies – user6353351 Nov 16 '22 at 22:47
  • Your code has errors. I believe that if you fix them, you will get the expected result (or close enough to warrant a question). – michael.hor257k Nov 17 '22 at 02:37
  • @michael.hor257k Apologies for the errors but i had to type the code in. Couldn't copy/paste. Errors have been fixed and I added some additional comments as to my issue. – user6353351 Nov 17 '22 at 17:25

1 Answers1

0

You only need to make a few minor adjustments to get the result you show:

XSLT 2.0

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/JournalFileData">
        <FileList>
            <xsl:for-each select="AccountingData">
                <xsl:variable name="common" select="* except JournalEntry" />
                <xsl:for-each-group select="JournalEntry" group-adjacent="(position() -1) idiv 5">
                    <File>
                        <JournalFileData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:js="urn:com.journal/JournalSource" js:Add="false">
                            <AccountingData>
                                <xsl:copy-of select="$common"/>
                                <xsl:copy-of select="current-group()"/>
                            </AccountingData>
                        </JournalFileData>
                    </File>
                </xsl:for-each-group>
            </xsl:for-each>
        </FileList>
    </xsl:template>

</xsl:stylesheet>
michael.hor257k
  • 113,275
  • 6
  • 33
  • 51
  • that gave me exactly what i needed. thank you for your assistance. i wasn't even aware of the 'except' operator. this is what was tripping me up – user6353351 Nov 17 '22 at 19:01