XSL is hard. The answers to my question here got me mostly on the right track, but there are a few small things that I initially overlooked. Here is my latest attempt:
XSL:
<!--
When a file is transformed using this stylesheet the output will be
formatted as follows:
1.) Elements named "info" will be removed
2.) Attributes named "file_line_nr" or "file_name" will be removed
3.) Comments will be removed
4.) Processing instructions will be removed
5.) XML declaration will be removed
6.) Extra whitespace will be removed
7.) Empty attributes will be removed
8.) Elements void of both attributes and child elements will be removed
9.) All elements will be sorted by name recursively
10.) All attributes will be sorted by name
-->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" method="xml" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<!--
Elements/attributes to remove. Note that comments are not elements or
attributes. Since there is no template to match comments they are
automatically ignored.
-->
<xsl:template match="@*[normalize-space()='']|info|@file_line_nr|@file_name"/>
<!-- Match any attribute -->
<xsl:template match="@*">
<xsl:copy>
<xsl:apply-templates select="@*"/>
</xsl:copy>
</xsl:template>
<!-- Match any element -->
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="@*">
<xsl:sort select="name()"/>
</xsl:apply-templates>
<xsl:apply-templates>
<xsl:sort select="name()"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
I think I have addressed every one of my requirements except number 8. I can successfully make a stylesheet that removes elements that don't have children, or that removes elements that do not have attributes, but that isn't what I want. I only want to remove elements that don't have attributes, child elements, or text.
Input XML:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?><!-- XML declaration should be removed -->
<foo b="b" a="a" c="c">
<?some-app inst="some instruction"?><!-- Processing instructions should be removed -->
<qwer><!-- Keep elements like this because it has child elements -->
<zxcv c="c" b="b"/><!-- Keep elements like this because it has attributes -->
<id>some text</id><!-- Keep elements like this because it has text -->
<info i="i"/><!-- Elements named "info" are to be removed -->
<rewq file_line_nr="42" file_name="somefile.txt"/><!-- Attributes named "file_line_nr" and "file_name" are to be removed which will leave this element empty, so it should be removed too -->
<vcxz c="c" b="b"/>
</qwer>
<baz e="e" d="d"/>
<bar>
<fdsa g="g" f="f"/>
<asdf g="g" f="f"/>
</bar>
</foo>
Desired Output XML: (No comments, no whitespace/indent, elements and attributes sorted)
<foo a="a" b="b" c="c">
<bar>
<asdf f="f" g="g"/>
<fdsa f="f" g="g"/>
</bar>
<baz d="d" e="e"/>
<qwer>
<id>some text</id>
<vcxz b="b" c="c"/>
<zxcv b="b" c="c"/>
</qwer>
</foo>