Human
Human

Reputation: 876

Why can't my script parse a xml file in a sub directory?

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

Answers (3)

Human
Human

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

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

Oleksii Filonenko
Oleksii Filonenko

Reputation: 1653

Try writing '/test' without the leading slash.

path_to_file = os.path.join(script_path, 'test', 'file.xml')

Upvotes: 1

Related Questions