A solution with XSLT would look like this:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" encoding="UTF-8" indent="no"/>
<xsl:template match="*|@*">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<!-- trim whitespaces from the content -->
<xsl:template match="text()">
<!-- remove from tag to content -->
<xsl:variable name="trimmedHead" select="replace(.,'^\s+','')"/>
<xsl:variable name="trimmed" select="replace($trimmedHead,'\s+$','')"/>
<xsl:value-of select="$trimmed"/>
</xsl:template>
<!-- do not trim where text content exist -->
<xsl:template match="text()">
<xsl:if test="not(matches(.,'^\s+$'))">
<xsl:value-of select="."/>
</xsl:if>
</xsl:template>
You can choose the template you would like to use. The first removes all whitespaces also when content exists, and the second one removes only when there are just whitespaces or newlines.