Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How can I factor this nested loop?

Status
Not open for further replies.

cpjust

Programmer
Sep 23, 2003
2,132
0
0
US
Hi, I have some ideas (using functors), but I'm not sure if there's a better way. I have this huge nested loop in Java, and each loop is virtually identical except the inner-most loop. Is there a way to factor each loop out into a separate function (preferable generic function) to reduce code duplication and brain overload when trying to look at 5 nested loops?
Code:
// Validate the format of all other sub-sections of the XML file.
for ( int authenticationIndex = 0; authenticationIndex < authenticationNodeList.getLength(); ++authenticationIndex )
{
	Node authenticationNode = authenticationNodeList.item( authenticationIndex );

	if ( authenticationNode.hasChildNodes() == false )
	{
		throw new XMLParseException( "XML format is invalid!  No child nodes under " + authenticationNode.getNodeName() );
	}

	NodeList nbuNodeList = authenticationNode.getChildNodes();
	Set<Set<Set<Set<UserStateFunctor>>>> authenticationSet = null;

	for ( int nbuIndex = 0; nbuIndex < nbuNodeList.getLength(); ++nbuIndex )
	{
		Node nbuNode = nbuNodeList.item( nbuIndex );

		if ( nbuNode.hasChildNodes() == false )
		{
			throw new XMLParseException( "XML format is invalid!  No child nodes under " + nbuNode.getNodeName() );
		}

		NodeList securityProviderNodeList = nbuNode.getChildNodes();
		Set<Set<Set<Set<UserStateFunctor>>>> securityProviderSet = null;

		for ( int spIndex = 0; spIndex < securityProviderNodeList.getLength(); ++spIndex )
		{
			Node securityProviderNode = securityProviderNodeList.item( spIndex );

			if ( securityProviderNode.hasChildNodes() == false )
			{
				throw new XMLParseException( "XML format is invalid!  No child nodes under " + securityProviderNode.getNodeName() );
			}

			NodeList bUserTypeNodeList = securityProviderNode.getChildNodes();
			Set<Set<Set<UserStateFunctor>>> bUserTypeSet = null;

			for ( int bUserTypeIndex = 0; bUserTypeIndex < bUserTypeNodeList.getLength(); ++bUserTypeIndex )
			{
				Node bUserTypeNode = bUserTypeNodeList.item( bUserTypeIndex );

				if ( bUserTypeNode.hasChildNodes() == false )
				{
					throw new XMLParseException( "XML format is invalid!  No child nodes under " + bUserTypeNode.getNodeName() );
				}

				NodeList logonTypeNodeList = bUserTypeNode.getChildNodes();
				Set<Set<UserStateFunctor>> logonTypeSet = null;

				for ( int logonTypeIndex = 0; logonTypeIndex < logonTypeNodeList.getLength(); ++logonTypeIndex )
				{
					Node logonTypeNode = logonTypeNodeList.item( logonTypeIndex );

					if ( logonTypeNode.hasChildNodes() == false )
					{
						throw new XMLParseException( "XML format is invalid!  No child nodes under " + logonTypeNode.getNodeName() );
					}

					NodeList checkNodeList = logonTypeNode.getChildNodes();
					Set<UserStateFunctor> userStateSet = getCheckStatesFromXML( checkNodeList );

					if ( (logonTypeSet.add( userStateSet ) == false) ||
						 (bUserTypeSet.add( logonTypeSet ) == false) ||
						 (securityProviderSet.add( bUserTypeSet ) == false) ||
						 (authenticationSet.add( bUserTypeSet ) == false) )
					{
						throw new XMLParseException( "XML format is invalid!" );
					}
				}	// End of logonTypeIndex loop.
			}	// End of bUserTypeIndex loop.
		}	// End of spIndex loop.
	}	// End of nbuIndex loop.
}	// authenticationIndex loop.
 
Any reason you can't use a schema to validate the document, rather than doing it yourself? Example from Sun, assuming you have J2SE 1.5

Code:
    // parse an XML document into a DOM tree
    DocumentBuilder parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    Document document = parser.parse(new File("instance.xml"));

    // create a SchemaFactory capable of understanding WXS schemas
    SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);

    // load a WXS schema, represented by a Schema instance
    Source schemaFile = new StreamSource(new File("mySchema.xsd"));
    Schema schema = factory.newSchema(schemaFile);

    // create a Validator instance, which can be used to validate an instance document
    Validator validator = schema.newValidator();

    // validate the DOM tree
    try {
        validator.validate(new DOMSource(document));
    } catch (SAXException e) {
        // instance document is invalid!
    }
seems a bit easier...

Steve

[small]"Every program can be reduced by one instruction, and every program has at least one bug. Therefore, any program can be reduced to one instruction which doesn't work." (Object::perlDesignPatterns)[/small]
 
Validating the XML isn't the only thing I'm doing with the loops. I'm also creating a set of objects to match what's in the XML.
 
I'd at least have a look at some sort of recursive proc call structure, if you haven't already.
 
I couldn't see an easy way to do that without leaving the resulting code as a nightmare to decipher.
It doesn't really matter now though, since after re-examining my original UML design, I needed a slightly different format anyways; so I broke out each loop into its own function...
 
At least you could use the enhanced for-loop, to make your code better readable.
Instead of:

Code:
 for (int nbuIndex = 0; nbuIndex < nbuNodeList.getLength (); ++nbuIndex)
	{
		Node nbuNode = nbuNodeList.item (nbuIndex);
you could simply write:
Code:
 for (Node nbuNode : nbuNodeList)
	{
, couldn't you?
I'm not used to parse XML and deal with those lists.

don't visit my homepage:
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top