Comment by bitwize
Parse, don't validate. Alexis King's article by that title should be fundamental reading for all distributed application developers. Go directly from on-the-wire representation to data structure with a well-defined type, and error if you can't. Use the type system to describe all representable objects. While this results in runtime errors on parse failure on the receiver's side, an advantage is that if the sender uses those same type definitions, you can guarantee that it will always send valid data.
Schemas should be derived from the type of the representation used in the application code, or vice-versa. If there are multiple schemas in use, there should be multiple corresponding types, perhaps with ways to interconvert between them. Schema changes will be less frequent, and easier to manage, with a bit of upfront systems analysis and design, including use of a data dictionary or complete IRM repository.
The more time you invest in thinking and planning what you want to build ahead of time, the fewer bugs and changes you'll have to worry about at runtime. The payoff is almost always more than worth the investment; "we don't have time to do things the right way" implies you have plenty of time to do things the wrong way.