Reputation: 876
When I try to parse a xml file in a sub directory I get a FileNotFoundError
. When I put the file next to the script it can parse it fine. But why?
#!/usr/bin/env python3
import os
import xml.etree.ElementTree as ET
script_path = os.path.dirname(os.path.realpath(__file__))
path_to_file = os.path.join(script_path, '/test', 'file.xml')
# works
tree = ET.parse('file.xml')
# Throws file not found error
tree = ET.parse(path_to_file)
Upvotes: 0
Views: 1112
Reputation: 876
I am posting the answer myself because although the answers solve the problem, they do not give the correct reason why their code works and mine doesn't.
The significant issue with my code is, that the line
path_to_file = os.path.join(script_path, '/test', 'file.xml')
# Expected value of path_to_file:
# /path/to/script/test/file.xml
# Output of print(path_to_file):
# /test/file.xml
contains the absolute path /test
instead of the relative path ./test
or as pointed out earlier the better way test
.
The result is that with /test
, the resulting path will not contain the contents of script_path
.
The previous answers might help in cases where you go down one directory, but don't cover cases like
path_to_file = os.path.join(script_path, 'test/subdir', 'file.xml')
Where you might find the /
useful. I think one can trust os.path.join()
to take care of those platform specific directories. Please let me know if you don't agree with me one this.
Upvotes: 0
Reputation: 6826
Try the easiest possible way of debugging by printing the value of path_to_file.
os.path.join()
is used so you don't have to specify the (os-specific) path separator character for the path it constructs, which means you don't need to (shouldn't) specify them.
You are over-specifying the path separator on the test
part - change:
path_to_file = os.path.join(script_path, '/test', 'file.xml')
to
path_to_file = os.path.join(script_path, 'test', 'file.xml')
Upvotes: 2
Reputation: 1653
Try writing '/test'
without the leading slash.
path_to_file = os.path.join(script_path, 'test', 'file.xml')
Upvotes: 1