Search code examples
xmljasper-reports

Reporting nested XML data in JasperSoft Studio


I have XML data like this:

<Event>
   <EventItems>
      <EventItem>
         <Error.Code>12345</Error.Code>
         <Short.Description>Something bad happened.</Short.Description>
         <Parameters>
            <Parameter>
               <Name>Blue thing</Name>
               <Value>25</Value>
            </Parameter>
            <Parameter>
               <Name>Red thing</Name>
               <Value>987BG</Value>
            </Parameter>
         </Parameters>
      </EventItem>
      <EventItem>
         <Error.Code>898765</Error.Code>
         <Short.Description>Minor Accident</Short.Description>
         <Parameters>
            <Parameter>
               <Name>Amazing thing</Name>
               <Value>Black</Value>
            </Parameter>
            <Parameter>
               <Name>Sad thing</Name>
               <Value>Tall</Value>
            </Parameter>
         </Parameters>
      </EventItem>
   </EventItems>
</Event>

And I want to display it like this via a Jasper report:

Record: 1
Error Code: 12345
Short Description: Something bad happened.
Blue thing: 25
Red thing: 987BG

Record: 2
Error Code: 898765
Short Description: Minor Accident.
Amazing thing: Black
Sad thing: Tall

Each EventItem will have an Error.Code, a Short.Description and any number of Parameter name value pairs. I have it outputting this much so far:

Record: 1
Error Code: 12345
Short Description: Something bad happened.

Record: 2
Error Code: 898765
Short Description: Minor Accident.

My report jrxml so far is below.

<?xml version="1.0" encoding="UTF-8"?>
<!-- Created with Jaspersoft Studio version 6.20.0.final using JasperReports Library version 6.20.0-2bc7ab61c56f459e8176eb05c7705e145cd400ad  -->
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="SimpleEvent_1" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="91198197-5168-4f47-85bd-bee341408674">
    <property name="com.jaspersoft.studio.data.defaultdataadapter" value="Data Adapter - Simple Event"/>
    <queryString language="xPath">
        <![CDATA[/Event/EventItems/EventItem]]>
    </queryString>
    <field name="Error.Code" class="java.lang.Integer">
        <property name="net.sf.jasperreports.xpath.field.expression" value="Error.Code"/>
        <fieldDescription><![CDATA[Error.Code]]></fieldDescription>
    </field>
    <field name="Short.Description" class="java.lang.String">
        <property name="net.sf.jasperreports.xpath.field.expression" value="Short.Description"/>
        <fieldDescription><![CDATA[Short.Description]]></fieldDescription>
    </field>
    <background>
        <band splitType="Stretch"/>
    </background>
    <title>
        <band height="79" splitType="Stretch"/>
    </title>
    <pageHeader>
        <band height="35" splitType="Stretch"/>
    </pageHeader>
    <columnHeader>
        <band height="61" splitType="Stretch"/>
    </columnHeader>
    <detail>
        <band height="125" splitType="Stretch">
            <textField>
                <reportElement x="281" y="48" width="278" height="30" uuid="b1df4f13-2ad6-4e05-9144-31e784c8a28d">
                    <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="ca44c831-b7ce-4af1-955e-69e68e3698c9"/>
                </reportElement>
                <textFieldExpression><![CDATA[$F{Error.Code}]]></textFieldExpression>
            </textField>
            <textField>
                <reportElement x="281" y="78" width="277" height="30" uuid="284a543b-0a62-475f-95fa-6922f1ab0589">
                    <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="6e3d3a9d-8d72-49f0-a9b8-98f4cb963f6a"/>
                </reportElement>
                <textFieldExpression><![CDATA[$F{Short.Description}]]></textFieldExpression>
            </textField>
            <staticText>
                <reportElement x="-9" y="78" width="277" height="30" uuid="265467a3-deeb-46da-a4d5-fd7a16f8c159">
                    <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="6e3d3a9d-8d72-49f0-a9b8-98f4cb963f6a"/>
                </reportElement>
                <text><![CDATA[Short.Description]]></text>
            </staticText>
            <staticText>
                <reportElement x="-10" y="47" width="278" height="30" uuid="d8eafefc-0fed-423a-99b8-816216d9b54c">
                    <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="ca44c831-b7ce-4af1-955e-69e68e3698c9"/>
                </reportElement>
                <text><![CDATA[Error.Code]]></text>
            </staticText>
            <textField>
                <reportElement x="281" y="10" width="100" height="30" uuid="4ea7e09a-b08f-4044-967f-556e503a6a3f"/>
                <textFieldExpression><![CDATA[$V{REPORT_COUNT}]]></textFieldExpression>
            </textField>
            <staticText>
                <reportElement x="-10" y="10" width="278" height="30" uuid="dc9e80f2-54fc-4422-bce5-11244e315aeb">
                    <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="ca44c831-b7ce-4af1-955e-69e68e3698c9"/>
                </reportElement>
                <text><![CDATA[Record:]]></text>
            </staticText>
        </band>
    </detail>
    <columnFooter>
        <band height="45" splitType="Stretch"/>
    </columnFooter>
    <pageFooter>
        <band height="54" splitType="Stretch"/>
    </pageFooter>
    <summary>
        <band height="42" splitType="Stretch"/>
    </summary>
</jasperReport>

What I am struggling with is how to access/report on the nested XML data. Should I use a sub-report? If so, how do I pass the parent XML record into the sub-report to it can access the child data it should report on?


Solution

  • Here is a working example I posted elsewhere: https://community.jaspersoft.com/forums/topic/67942-output-nested-data-in-a-list/

    XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <Event>
       <EventItems>
          <EventItem>
             <Error.Code>AXCB</Error.Code>
             <Severity.Code>Error</Severity.Code>
             <Parameters>
                <Parameter>
                   <Parameter.Identifier>ReportPartyTypeDimension</Parameter.Identifier>
                   <Parameter.Text>Payee</Parameter.Text>
                </Parameter>
             </Parameters>
          </EventItem>
          <EventItem>
             <Error.Code>BGDFD</Error.Code>
             <Severity.Code>Warning</Severity.Code>
             <Parameters>
                <Parameter>
                   <Parameter.Identifier>ContextID</Parameter.Identifier>
                   <Parameter.Text>09978qwew</Parameter.Text>
                </Parameter>
                <Parameter>
                   <Parameter.Identifier>Scheme</Parameter.Identifier>
                   <Parameter.Text>Some scheme</Parameter.Text>
                </Parameter>
                <Parameter>
                   <Parameter.Identifier>Identifier</Parameter.Identifier>
                   <Parameter.Text>586144911</Parameter.Text>
                </Parameter>
             </Parameters>
          </EventItem>
       </EventItems>
    </Event>
    

    And the Jasper report file:

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- Created with Jaspersoft Studio version 6.20.0.final using JasperReports Library version 6.20.0-2bc7ab61c56f459e8176eb05c7705e145cd400ad  -->
    <jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="Responses_multiple_no-namespaces_simplified" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="bcb3c989-8b7b-4498-a248-89d6c507b3f6">
        <property name="com.jaspersoft.studio.data.defaultdataadapter" value="Data Adapter - Multiple Responses - No Namespaces - Simplified"/>
        <subDataset name="EventItem_Parameters_Dataset" uuid="1c4eed1d-1cb4-4bed-982f-680f43dd95d6">
            <property name="com.jaspersoft.studio.data.defaultdataadapter" value="Data Adapter - Multiple Responses - No Namespaces - Simplified"/>
            <queryString language="xPath">
                <![CDATA[/Event/EventItems/EventItem/Parameters/Parameter]]>
            </queryString>
            <field name="Parameter.Identifier" class="java.lang.String">
                <property name="net.sf.jasperreports.xpath.field.expression" value="Parameter.Identifier"/>
                <fieldDescription><![CDATA[Parameter.Identifier]]></fieldDescription>
            </field>
            <field name="Parameter.Text" class="java.lang.String">
                <property name="net.sf.jasperreports.xpath.field.expression" value="Parameter.Text"/>
                <fieldDescription><![CDATA[Parameter.Text]]></fieldDescription>
            </field>
        </subDataset>
        <queryString language="xPath">
            <![CDATA[/Event/EventItems/EventItem]]>
        </queryString>
        <field name="Error.Code" class="java.lang.String">
            <property name="net.sf.jasperreports.xpath.field.expression" value="Error.Code"/>
            <fieldDescription><![CDATA[Error.Code]]></fieldDescription>
        </field>
        <field name="Severity.Code" class="java.lang.String">
            <property name="net.sf.jasperreports.xpath.field.expression" value="Severity.Code"/>
            <fieldDescription><![CDATA[Severity.Code]]></fieldDescription>
        </field>
        <detail>
            <band height="222" splitType="Stretch">
                <textField>
                    <reportElement x="90" y="0" width="139" height="19" uuid="ee828d4d-b903-4bb1-97de-fb001184983c">
                        <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="b6f0e574-74a1-4049-a044-3acd0bfd5f7d"/>
                    </reportElement>
                    <textFieldExpression><![CDATA[$F{Error.Code}]]></textFieldExpression>
                </textField>
                <textField>
                    <reportElement x="350" y="0" width="277" height="19" uuid="910ae679-1486-4dbf-bf52-b6df009a4e60">
                        <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="bce7ec08-c457-44d6-9eb8-f08e147fb210"/>
                    </reportElement>
                    <textFieldExpression><![CDATA[$F{Severity.Code}]]></textFieldExpression>
                </textField>
                <textField>
                    <reportElement x="0" y="20" width="102" height="18" uuid="08509c7c-d0e0-4f1a-8634-1239ca262f65"/>
                    <textFieldExpression><![CDATA["Parameters"]]></textFieldExpression>
                </textField>
                <componentElement>
                    <reportElement x="9" y="50" width="545" height="30" uuid="3803a4ec-e17a-4e8d-b187-279ad6741f16"/>
                    <jr:list xmlns:jr="http://jasperreports.sourceforge.net/jasperreports/components" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports/components http://jasperreports.sourceforge.net/xsd/components.xsd" printOrder="Vertical">
                        <datasetRun subDataset="EventItem_Parameters_Dataset" uuid="67f528e2-94bb-46b8-9f76-ed52f4cd45a4">
                            <dataSourceExpression><![CDATA[((net.sf.jasperreports.engine.data.JRXmlDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("/EventItem/Parameters/Parameter")]]></dataSourceExpression>
                        </datasetRun>
                        <jr:listContents height="30" width="545">
                            <textField>
                                <reportElement x="170" y="0" width="375" height="30" uuid="7839d387-0121-402f-b71a-15c679697104"/>
                                <textFieldExpression><![CDATA[$F{Parameter.Identifier}]]></textFieldExpression>
                            </textField>
                            <textField>
                                <reportElement x="0" y="0" width="170" height="30" uuid="2e374982-5c06-408f-adac-bbd975203783"/>
                                <textFieldExpression><![CDATA[$F{Parameter.Text}]]></textFieldExpression>
                            </textField>
                        </jr:listContents>
                    </jr:list>
                </componentElement>
                <staticText>
                    <reportElement x="0" y="-1" width="90" height="20" uuid="50a0d324-b27b-4d3d-9d40-638e9ca0bd2c">
                        <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="b6f0e574-74a1-4049-a044-3acd0bfd5f7d"/>
                        <property name="com.jaspersoft.studio.unit.height" value="px"/>
                    </reportElement>
                    <text><![CDATA[Error.Code]]></text>
                </staticText>
                <staticText>
                    <reportElement x="238" y="-1" width="112" height="20" uuid="eeb72e9a-5bf3-4332-9aeb-6c54264bb324">
                        <property name="com.jaspersoft.studio.spreadsheet.connectionID" value="bce7ec08-c457-44d6-9eb8-f08e147fb210"/>
                        <property name="com.jaspersoft.studio.unit.height" value="px"/>
                    </reportElement>
                    <text><![CDATA[Severity.Code]]></text>
                </staticText>
            </band>
        </detail>
    </jasperReport>
    

    The key issue is that the inner XPATH must be relative to the outer XPATH.

    Outer: /Event/EventItems/EventItem

    Inner: ((net.sf.jasperreports.engine.data.JRXmlDataSource)$P{REPORT_DATA_SOURCE}).subDataSource("/EventItem/Parameters/Parameter")