Quick answer: Remove -H "Content-Type: text/xml" and it should work.
The problem is that when a file is sent, the Content-Type header should be multipart/form-data, which curl sets automatically when you use -F. From curls documentation:
-F, --form 
                (HTTP)  This  lets  curl emulate a filled-in form in which a user has pressed the submit
                button. This causes curl to POST data using the Content-Type multipart/form-data according to RFC 2388. This enables uploading of binary files etc.
However, you are overwriting this header with -H, so your app is expecting something that is not a file.
If, in addition to sending the file with curl, you want to include information about its type, you should instead do this:
curl -X POST -F "file_data=@test.xml;type=text/xml" http://localhost:4567/test
(The content type comes after the file name and a semicolon.)
To see how a raw form submission request ends up looking like with multipart/form-data, check the answers to this question.