xmllint has options that can be used to produce the desired output. From the help:
--c14n : save in W3C canonical format v1.0 (with comments)
--c14n11 : save in W3C canonical format v1.1 (with comments)
--exc-c14n : save in W3C exclusive canonical format (with comments)
Using any one of these would work
xmllint --c14n test.xml
Unfortunately, combining several formatting options in one xmllint call does not seem to work, so if you e.g. additionally want to use --format to have xmllint reformat/reindent the output, you will need to pipe the output from the first xmllint call into a second one. When doing this, it seems that xmllint requires the - stdin redirect be at the end of the command.
Example:
For test.xml as
<?xml version="1.0" encoding="UTF-8"?>
<outer><inner/></outer>
the command
xmllint --format test.xml | xmllint --c14n -
produces the output
<outer>
<inner></inner>
</outer>
Notes:
- since the
--format option would collapse the expanded empty tag again, the order of the options in the pipe matters
- the above options remove the xml declaration / omit it in the first line of the output