Outputting nested bean properties

Christopher Koenigsberg

OK here is a reconstruction of my example that got nuked, please feel free to correct, enhance, comment etc.

This example is using Struts tags ("logic:present"/notPresent, "logic:iterate" nested 2 levels, "bean:size", "logic:greaterThan"/lessEqual, and "bean:write"), no scriptlets, to display search results, presumably returned previously and already set into session scope, as "your2DResultsCollectionBean", assumed to be a 2-dimensional implementation of java.util.Collections interface (e.g. "List" rows of "List" columns, of "String" value):

<logic:notPresent name="your2DResultsCollectionBean" scope="session">
<h3>Sorry, no results were returned! (contact the Webmaster?)</h3>

<logic:present name="your2DResultsCollectionBean" scope="session">
<bean:size id="numResults" name="your2DResultsCollectionBean"  scope="session" />

<logic:lessEqual value="0" name="numResults"  scope="page">
<h3>Sorry, your search returned zero results! Please try again!</h3>

<logic:greaterThan value="0" name="numResults"  scope="page">
<p><strong> Congratulations, your search returned</strong></p>
<h4>  <bean:write name="numResults" scope="page"/> results:</h4>

<logic:iterate id="ResultsRowCollectionBean" name="your2DResultsCollectionBean"
	 indexId="rowNum" scope="request">
	<logic:present name="ResultsRowCollectionBean scope="page">
                    Result row number:
                    <bean:write name="rowNum" scope="page"/>
                  <logic:iterate id="ResultsColumnStringBean" name="ResultsRowCollectionBean"
			indexId="ColNum" type="java.lang.String" scope="page">

			<logic:present name="ResultsColumnStringBean" scope="page">
                                  <bean:write name="colNum" scope="page"/>
                                  ,  Value: 
                                     <!-- the "filter=false" will preserve any embedded HTML formatting tags -->
				  <bean:write name="ResultsColumnStringBean" scope="page" filter="false"/>

			<logic:notPresent name="ResultsColumn" scope="page">
                                  (empty column)


	<logic:notPresent name="ResultsRow" scope="page">
            (     empty row)



Note that if the "your2DResultsCollectionBean" at the outer level implemented java.util.Map rather than java.util.List, you would have to use "key" or "value" in accessing the current row inside the outer iterator e.g. say if you had rowNumber as the Map key and rowContents as a "List" as the value of the Map element for that row, you would name something like "resultsRowCollectionBean.value", as the "name" attribute of the source bean for the inner logic:iterate, and "resultsRowCollectionBean.key" would give you the Map getKey which in this case would presumably equal your rowNumber...

Also if your columns did not just contain Strings, you would have to call their toString() or something like that, in displaying the column contents (e.g. the "ResultsColumnStringBean" would need some explicit accessor method to be called by the innermost bean:write, if it wasn't just a String).