Instead of simply checking for the root element based on the argument is_root, we should instead either pass in some sort of validator or allow the function to return the element name so it can be used in a validator.
Write a stream abstraction for handling ftp:// type URIs and add a function to create and return such streams. That is the only chunk missing in the armour.