Excerpt is only getting shown for first post

I suspect you’re misusing query_posts(), which is always and only ever intended to modify the Primary Loop.

query_posts() is meant for altering the main loop. Once you use query_posts(), your post-related global variables and template tags will be altered. Conditional tags that are called after you call query_posts() will also be altered – this may or may not be the intended result.

If, as I assume, you’re outputting it multiple times, then by definition, you’re creating secondary Loops, for which you should use WP_Query or get_posts() instead.

But I’m somewhat confused by the flow of the code, due to lack of consistent indentation.

EDIT

Based on this comment:

I’ve set my category.php file up so it displays my categories, then sub-categories if it has any. If it doesn’t have any it shows my posts belonging to that category.

Let’s try to lay out logically what you want category.php to display.

Assumptions

  1. First, display Custom Post Types that are in the current category
  2. Second, additional loops are used to display Custom Post Types that are in child categories of the current category
  3. If Custom Post Types in neither the current category nor its child categories exist, display Blog Posts that are in the current category.
  4. Categorized or child-categorized Custom Post Types always display, if they exist
  5. Categorized Blog Posts only display if CPTs do not exist

All good so far?