Python - XML 파싱, 태그 또는 요소 별로 읽기

파이썬에서 XML 파일이나 문자열을 파싱하고, Tag나 attribute 별로 Element를 읽는 방법을 소개합니다.

1. XML 파일 파싱

ElementTree.parse(file)는 인자로 전달된 파일을 파싱하고 ElementTree 객체로 리턴합니다.

import xml.etree.ElementTree as ET


filePath = "./example.xml"
tree = ET.parse(filePath)
ET.dump(tree)

Output:

<Countries><Korea><City>Seoul</City></Korea><Japanese><City>Tokyo</City></Japanese></Countries>

1.1 파싱한 객체를 보기 좋게 출력 : Text에 Tab, 개행 문자 추가

위의 코드에서, _pretty_print()를 추가로 구현하여, 파싱한 xml 객체의 text에 Tab과 개행 문자를 추가하면 다음과 같이 보기 좋게 출력할 수 있습니다.

import xml.etree.ElementTree as ET


def _pretty_print(current, parent=None, index=-1, depth=0):
    for i, node in enumerate(current):
        _pretty_print(node, current, i, depth + 1)
    if parent is not None:
        if index == 0:
            parent.text = '\n' + ('\t' * depth)
        else:
            parent[index - 1].tail = '\n' + ('\t' * depth)
        if index == len(parent) - 1:
            current.tail = '\n' + ('\t' * (depth - 1))


filePath = "./example.xml"
tree = ET.parse(filePath)

_pretty_print(tree.getroot())

ET.dump(tree)

Output:

<Countries>
	<Korea>
		<City attr1="value1" attr2="value2">Seoul</City>
	</Korea>
	<Japanese>
		<City attr1="value1" attr2="value2">Tokyo</City>
	</Japanese>
</Countries>

2. XML 문자열 파싱

ElementTree.fromstring()은 XML 문자열을 인자로 받고, 파싱한 결과를 Element 객체로 리턴합니다.

import xml.etree.ElementTree as ET


xml_str = "<Countries><Korea><City>Seoul</City></Korea><Japanese><City>Tokyo</City></Japanese></Countries>"

element = ET.fromstring(xml_str)
ET.dump(element)

Output:

<Countries><Korea><City>Seoul</City></Korea><Japanese><City>Tokyo</City></Japanese></Countries>

3. XML 파싱하고, 요소 별로 읽기

다음과 같이 XML을 파싱하여 Element 객체를 얻고 요소 별로 접근할 수 있습니다. findall()로 모든 태그를 찾을 수 있고, attrib로 Element의 attribute에 접근할 수 있습니다. XML의 텍스트는 text로 접근할 수 있습니다. Element의 하위 Element는 find()findall()로 접근할 수 있습니다.

import xml.etree.ElementTree as ET


xml_str = '''<?xml version='1.0' encoding='utf-8'?>
<Countries>
    <Country name="Korea">
        <City attr1="value1" attr2="value2">Seoul</City>
    </Country>
    <Country name="Japanese">
        <City attr1="value1" attr2="value2">Tokyo</City>
    </Country>
</Countries>
'''

root = ET.fromstring(xml_str)

for country in root.findall("Country"):
    attr = country.attrib
    name = attr.get("name")
    city = country.find("City")
    city_name = city.text
    city_attr1 = city.attrib.get("attr1")
    city_attr2 = city.attrib.get("attr2")
    print(f"attr : {attr}")
    print(f"name : {name}")
    print(f"attr : {attr}")
    print(f"city_name : {city_name}")
    print(f"city_attr1 : {city_attr1}")
    print(f"city_attr2 : {city_attr2}")

Output:

attr : {'name': 'Korea'}
name : Korea
attr : {'name': 'Korea'}
city_name : Seoul
city_attr1 : value1
city_attr2 : value2
attr : {'name': 'Japanese'}
name : Japanese
attr : {'name': 'Japanese'}
city_name : Tokyo
city_attr1 : value1
city_attr2 : value2
Loading script...
codechachaCopyright ©2019 codechacha