[Python 모듈] xml : XML 데이터를 처리하기 위한 모듈

 

1. xml 모듈이란?

 

xml 모듈은 파이썬에서 XML 데이터를 처리하기 위한 모듈입니다. XML 데이터를 파싱하고, 생성하고, 수정하는 기능을 제공합니다. xml 모듈의 주요 클래스로는 ElementTree와 Element가 있습니다. ElementTree 클래스는 XML 트리를 생성하고 조작하는 클래스이며, Element 클래스는 XML 요소를 나타내는 클래스입니다.

 

xml모듈은 별도의 설치 과정이 필요없습니다. 모듈을 사용하려면 아래와 같이 import를 하면 됩니다.

import xml

 


2. Element

 

Element 클래스는 XML 요소(Element)를 나타내며, 요소(Element)의 이름과 속성(attribute), 하위 요소(sub-element), 텍스트(text) 등을 포함합니다. Element는 요소(Element)의 생성, 수정, 삭제 등의 작업을 수행할 수 있습니다.

 


2.1 find

 

find() 함수는 지정한 태그명과 일치하는 첫 번째 하위 요소(Element)를 찾아 반환합니다. 이 함수는 XML 요소의 구조를 파악하고 필요한 정보를 추출하는 데에 유용합니다.

 

예를 들어, 다음과 같은 XML 구조를 가진 문자열이 있다고 가정해봅시다.

<book>
  <title>Python Programming</title>
  <author>John Smith</author>
  <publisher>Packt Publishing</publisher>
  <year>2022</year>
</book>

 

이 코드는 XML 문자열을 파싱하여 ElementTree 객체를 생성하고, 이를 통해 title 요소를 찾아내는 코드입니다. 코드를 실행하면 "Python Programming"이라는 문자열이 출력됩니다. 즉, Element.find() 함수를 사용하여 title 요소를 찾아내고, 해당 요소의 text 속성을 출력하는 것입니다.

import xml.etree.ElementTree as ET

# XML 문자열
xml_str = "<book><title>Python Programming</title><author>John Smith</author><publisher>Packt Publishing</publisher><year>2022</year></book>"

# ElementTree 객체 생성
root = ET.fromstring(xml_str)

# title 요소 찾기
title_elem = root.find("title")
print(title_elem.text)

 


2.2 findall

 

findall() 함수는 지정한 태그명과 일치하는 모든 하위 요소(Element)를 찾아 리스트로 반환합니다. 이 함수는 XML 문서에서 특정 요소들을 선택해 추출하는 데에 유용합니다.



예를 들어, 다음과 같은 XML 구조를 가진 문자열이 있다고 가정해봅시다.

<fruits>
  <fruit name="apple" color="red">Sweet and juicy</fruit>
  <fruit name="banana" color="yellow">Rich in potassium</fruit>
  <fruit name="orange" color="orange">High in vitamin C</fruit>
  <fruit name="kiwi" color="brown">Rich in fiber</fruit>
</fruits>

 

이 코드는 XML 문자열을 파싱하여 ElementTree 객체를 생성하고, 이를 통해 모든 과일(fruit) 요소를 찾아내는 코드입니다. 즉, Element.findall() 함수를 사용하여 모든 과일 요소를 찾아내고, 각 요소의 속성과 텍스트 값을 출력하는 것입니다.

import xml.etree.ElementTree as ET

# XML 문자열
xml_str = "<fruits><fruit name=\"apple\" color=\"red\">Sweet and juicy</fruit><fruit name=\"banana\" color=\"yellow\">Rich in potassium</fruit><fruit name=\"orange\" color=\"orange\">High in vitamin C</fruit><fruit name=\"kiwi\" color=\"brown\">Rich in fiber</fruit></fruits>"

# ElementTree 객체 생성
root = ET.fromstring(xml_str)

# 과일(fruit) 요소 찾기
fruit_elems = root.findall("fruit")

# 모든 과일 요소 출력하기
for fruit_elem in fruit_elems:
    name = fruit_elem.get("name")
    color = fruit_elem.get("color")
    description = fruit_elem.text
    print(name, color, description)
    
    
#apple red Sweet and juicy
#banana yellow Rich in potassium
#orange orange High in vitamin C
#kiwi brown Rich in fiber

 

 


2.3 get

 

get() 함수는 지정된 요소의 지정된 속성 값을 반환합니다.

예를 들어, 다음과 같은 XML 코드가 있다고 가정해보겠습니다.

<book id="bk101">
   <author>Gambardella, Matthew</author>
   <title>XML Developer's Guide</title>
   <genre>Computer</genre>
   <price>44.95</price>
   <publish_date>2000-10-01</publish_date>
   <description>An in-depth look at creating applications 
   with XML.</description>
</book>

 

여기서 book 요소의 id 속성 값을 가져오려면, ElementTree 객체를 사용하여 해당 요소를 찾고 get() 함수를 사용하여 해당 속성 값을 가져와야 합니다. 코드에서, 먼저 xml 파일을 파싱하여 ElementTree 객체를 만들고, 루트 요소를 가져옵니다. 그 다음, find() 함수를 사용하여 book 요소를 찾고, get() 함수를 사용하여 해당 요소의 id 속성 값을 가져옵니다. 가져온 값을 출력하면 "bk101"이라는 결과가 나옵니다.

import xml.etree.ElementTree as ET

tree = ET.parse('books.xml')
root = tree.getroot()

book = root.find('book')
id = book.get('id')

print(id)  # 출력 결과: bk101

 

 


2.4 set

 

set() 함수는 지정된 요소의 지정된 속성 값을 설정합니다.



예를 들어, 다음과 같은 XML 코드가 있다고 가정해보겠습니다.

<book>
   <title>Harry Potter and the Philosopher's Stone</title>
   <author>J.K. Rowling</author>
</book>

 

여기서, book 요소에 publisher 속성을 추가하고 그 값을 Bloomsbury Publishing으로 설정하려면, ElementTree 객체를 사용하여 해당 요소를 찾고 set() 함수를 사용하여 속성 값을 설정해야 합니다. 코드에서, 먼저 xml 파일을 파싱하여 ElementTree 객체를 만들고, 루트 요소를 가져옵니다. 그 다음, find() 함수를 사용하여 book 요소를 찾고, set() 함수를 사용하여 publisher 속성 값을 설정합니다. 마지막으로, write() 함수를 사용하여 변경된 ElementTree 객체를 XML 파일에 씁니다. 이제 books.xml 파일을 열어보면, book 요소에 publisher 속성이 추가되어 있는 것을 확인할 수 있습니다.

import xml.etree.ElementTree as ET

tree = ET.parse('books.xml')
root = tree.getroot()

book = root.find('book')
book.set('publisher', 'Bloomsbury Publishing')

tree.write('books.xml')

 

 


2.5 text

 

text는 해당 요소의 텍스트 콘텐츠를 가져옵니다.



예를 들어, 다음과 같은 XML 코드가 있다고 가정해보겠습니다.

<book>
   <title>Harry Potter and the Philosopher's Stone</title>
   <author>J.K. Rowling</author>
</book>

 

여기서, title 요소의 텍스트 값을 가져오려면 Element.text를 사용하여 title 요소를 찾고 텍스트 값을 가져와야 합니다. 코드에서, 먼저 xml 파일을 파싱하여 ElementTree 객체를 만들고, 루트 요소를 가져옵니다. 그 다음, find() 함수를 사용하여 title 요소를 찾고, text 속성을 사용하여 해당 요소의 텍스트 값을 가져옵니다. 마지막으로, print() 함수를 사용하여 텍스트 값을 출력합니다. 이제 코드를 실행하면, "Harry Potter and the Philosopher's Stone"이라는 텍스트가 출력됩니다.

import xml.etree.ElementTree as ET

tree = ET.parse('books.xml')
root = tree.getroot()

title = root.find('book/title')
print(title.text)

 

 


2.6 tag

 

tag는 해당 요소의 태그 이름을 가져옵니다.



예를 들어, 다음과 같은 XML 코드가 있다고 가정해보겠습니다.

<book>
   <title>Harry Potter and the Philosopher's Stone</title>
   <author>J.K. Rowling</author>
</book>

 

여기서, book 요소의 태그 이름을 가져오려면 Element.tag를 사용하여 book 요소를 찾아야 합니다. 코드에서, 먼저 xml 파일을 파싱하여 ElementTree 객체를 만들고, 루트 요소를 가져옵니다. 그 다음, find() 함수를 사용하여 book 요소를 찾고, tag 속성을 사용하여 해당 요소의 태그 이름을 가져옵니다. 마지막으로, print() 함수를 사용하여 태그 이름을 출력합니다. 이제 코드를 실행하면, "book"이라는 태그 이름이 출력됩니다.

import xml.etree.ElementTree as ET

tree = ET.parse('books.xml')
root = tree.getroot()

book = root.find('book')
print(book.tag)

 

 


2.7 attrib

 

attrib는 해당 요소의 속성(attribute)을 딕셔너리 형태로 가져옵니다.



예를 들어, 다음과 같은 XML 코드가 있다고 가정해보겠습니다.

<book ISBN="9788968480189">
   <title>Harry Potter and the Philosopher's Stone</title>
   <author>J.K. Rowling</author>
</book>

 

여기서, book 요소의 속성을 가져오려면 Element.attrib를 사용하여 book 요소를 찾아야 합니다. 코드에서, 먼저 xml 파일을 파싱하여 ElementTree 객체를 만들고, 루트 요소를 가져옵니다. 그 다음, find() 함수를 사용하여 book 요소를 찾고, attrib 속성을 사용하여 해당 요소의 속성을 가져옵니다. 마지막으로, print() 함수를 사용하여 속성을 출력합니다. 이제 코드를 실행하면, {"ISBN": "9788968480189"}라는 딕셔너리 형태로 속성이 출력됩니다.

import xml.etree.ElementTree as ET

tree = ET.parse('books.xml')
root = tree.getroot()

book = root.find('book')
print(book.attrib)

 

 


2.8 append

 

append는 지정한 요소(Element)를 해당 요소(Element)의 하위 요소(sub-element)로 추가합니다. 속성이 없는 경우, 빈 딕셔너리를 반환합니다. 또한, 여러 개의 속성이 있는 경우 딕셔너리에 모든 속성이 포함됩니다.

 

예를 들어, 다음과 같은 XML 코드가 있다고 가정해보겠습니다.

<book ISBN="9788968480189" language="en">
   <title>Harry Potter and the Philosopher's Stone</title>
   <author>J.K. Rowling</author>
</book>

 

예를 들어, 위의 XML 코드에서 book 요소의 ISBN 속성을 "9788968480190"으로 변경하려면 다음과 같이 코드를 작성합니다. 이제 코드를 실행하면, {"ISBN": "9788968480190", "language": "en"}가 출력됩니다.

book.set('ISBN', '9788968480190')
print(book.attrib)

 


2.9 remove

 

remove() 함수는 Element 객체에서 자식 Element를 삭제합니다. 이 함수는 해당 Element 객체에서 첫 번째로 발견된 자식 Element를 삭제하며, 만약 지정한 태그 이름과 일치하는 자식 Element가 없으면 아무런 작업을 하지 않습니다.



예를 들어, 다음과 같은 XML 문서가 있다고 가정해봅시다.

<root>
  <person id="1">
    <name>Alice</name>
    <age>25</age>
  </person>
  <person id="2">
    <name>Bob</name>
    <age>30</age>
  </person>
  <person id="3">
    <name>Charlie</name>
    <age>35</age>
  </person>
</root>

 

여기서, root Element 객체를 생성하고, person Element 중에서 id 속성 값이 2인 Element를 삭제하는 코드는 다음과 같습니다. 코드에서는 root.findall('person') 메소드로 person 태그를 가진 모든 Element 객체를 찾은 후, get() 메소드로 id 속성 값이 2인 Element를 찾습니다. 그리고 root.remove(person)을 사용하여 해당 Element를 삭제합니다. 마지막으로, ET.dump(root)를 사용하여 결과를 출력합니다.

import xml.etree.ElementTree as ET

# XML 문서 파싱
tree = ET.parse('example.xml')
root = tree.getroot()

# id 속성 값이 2인 person Element를 삭제
for person in root.findall('person'):
    if person.get('id') == '2':
        root.remove(person)

# 결과 출력
ET.dump(root)

 

코드를 실행하면, 다음과 같은 XML 문서가 출력됩니다.

<root>
  <person id="1">
    <name>Alice</name>
    <age>25</age>
  </person>
  <person id="3">
    <name>Charlie</name>
    <age>35</age>
  </person>
</root>

 

 


3. ElementTree

 

ElementTree 클래스는 XML 문서를 읽어들이고, 요소(Element) 객체의 트리를 생성합니다. 이 트리는 요소(Element) 객체들의 계층 구조를 표현합니다. ElementTree는 또한 XML 요소(Element)를 찾아보거나, 요소(Element) 객체를 생성하고, 수정하거나, 삭제하는 등의 작업을 수행할 수 있습니다.

 


3.1 parse

 

parse() 함수는 XML 파일을 파싱하여 XML 문서의 루트 요소를 반환합니다. 파싱된 XML 문서를 ElementTree 객체로 표현하며, 이 객체는 XML 문서의 요소에 대한 트리 구조를 가지며 각 요소는 Element 객체로 표현됩니다. parse() 함수는 파일 이름이나 파일 객체를 매개변수로 받습니다. 파일 이름을 전달하는 경우, 함수는 해당 파일을 열고 파싱을 수행합니다. 파일 객체를 전달하는 경우, 함수는 파일 객체를 파싱하여 XML 문서를 생성합니다.



예를 들어, example.xml 파일을 파싱하여 ElementTree 객체로 변환하는 코드는 다음과 같습니다. 코드에서 parse() 함수는 example.xml 파일을 파싱하여 tree 객체로 변환합니다. getroot() 메소드를 호출하여 파싱된 XML 문서의 루트 요소를 가져옵니다. 이 요소는 root 변수에 할당됩니다. 이제 root 변수를 사용하여 XML 문서의 요소에 접근할 수 있습니다.

import xml.etree.ElementTree as ET

tree = ET.parse('example.xml')
root = tree.getroot()

 

 


3.2 fromstring

 

fromstring 함수는 XML 문자열을 파싱하여 Element 객체를 반환하는 함수입니다. 즉, 문자열로 구성된 XML 데이터를 파싱하여 Element 객체로 만드는 역할을 합니다.



코드에서는 xml_string 변수에 XML 문자열을 저장한 후, fromstring() 함수를 사용하여 파싱하고, 반환된 Element 객체를 root 변수에 저장합니다. 

import xml.etree.ElementTree as ET

xml_string = "<person><name>Alice</name><age>25</age></person>"
root = ET.fromstring(xml_string)

 

 

 

 


3.3 getroot

 

getroot() 함수는 파싱된 XML 문서의 루트 엘리먼트를 반환합니다. XML 문서를 파싱한 후 ElementTree 객체를 생성하면, getroot() 함수를 사용하여 루트 엘리먼트를 가져올 수 있습니다.

 

아래 코드에서 example.xml 파일을 파싱한 후, getroot() 함수를 사용하여 해당 XML 문서의 루트 엘리먼트를 가져옵니다. 가져온 루트 엘리먼트는 root 변수에 할당됩니다.

import xml.etree.ElementTree as ET

# XML 문서 파싱
tree = ET.parse('example.xml')

# 루트 엘리먼트 가져오기
root = tree.getroot()

 

 


3.4 write

 

write() 함수는 XML 요소를 파일에 쓰는 함수입니다. 

 

함수의 구문은 다음과 같습니다.

 

  • file: XML을 쓸 파일의 경로 또는 파일 객체입니다.
  • encoding: XML 파일의 인코딩을 지정합니다.
  • xml_declaration: True로 설정하면 XML 선언을 추가합니다. 기본값은 None입니다.
  • default_namespace: 요소에 대한 기본 네임 스페이스를 지정합니다.
  • method: 출력 방법을 지정합니다.
  • short_empty_elements: 빈 요소를 짧은 형식으로 쓸지 여부를 결정합니다. True로 설정하면 <tag/> 형식으로 쓰입니다. 기본값은 True입니다.

 

ElementTree.write(file, encoding="us-ascii", xml_declaration=None, default_namespace=None, method="xml", *, short_empty_elements=True)

 

 

아래 코드는 ElementTree 객체를 생성하고 XML 파일에 쓰는 예시입니다.

import xml.etree.ElementTree as ET

# XML 요소 생성
root = ET.Element("book")
title = ET.SubElement(root, "title")
title.text = "The Hitchhiker's Guide to the Galaxy"
author = ET.SubElement(root, "author")
author.text = "Douglas Adams"

# XML 파일에 쓰기
tree = ET.ElementTree(root)
tree.write("book.xml")

 

코드를 실행하면, 다음과 같은 book.xml 파일을 생성합니다.

<book>
    <title>The Hitchhiker's Guide to the Galaxy</title>
    <author>Douglas Adams</author>
</book>

 


3.5 tostring

 

tostring 함수는 Element 객체를 이용하여 XML 문자열을 생성하는 함수입니다. 이 함수는 Element 객체를 인자로 받아 해당 객체를 나타내는 XML 문자열을 반환합니다. 이때 인자로 전달된 Element 객체는 XML 문서의 루트 엘리먼트여야 합니다.



예를 들어, 다음과 같은 XML 문서가 있다고 가정해 봅시다.

<book>
  <title>The Catcher in the Rye</title>
  <author>J.D. Salinger</author>
  <year>1951</year>
</book>

 

아래 코드는 XML 문서를 파싱하여 Element 객체로 변환한 후, ElementTree.tostring 함수를 이용하여 XML 문자열로 다시 변환하는 코드입니다.

import xml.etree.ElementTree as ET

xml_str = '''<book>
                <title>The Catcher in the Rye</title>
                <author>J.D. Salinger</author>
                <year>1951</year>
            </book>'''

root = ET.fromstring(xml_str)

xml_output = ET.tostring(root)
print(xml_output.decode())

 

코드를 실행하면 다음과 같은 출력 결과가 나옵니다.

<b'book>\n  <title>The Catcher in the Rye</title>\n  <author>J.D. Salinger</author>\n  <year>1951</year>\n</book>'

 

 


3.6 iter

 

iter 함수는 주어진 태그의 자식 요소를 포함하여 해당 태그를 포함하는 요소를 순회하는 이터레이터(iterator)를 반환합니다.

 

예를 들어, 다음과 같은 XML 문서가 있다고 가정해보겠습니다.

<books>
    <book id="001">
        <title>The Catcher in the Rye</title>
        <author>J.D. Salinger</author>
        <year>1951</year>
        <price>19.99</price>
    </book>
    <book id="002">
        <title>To Kill a Mockingbird</title>
        <author>Harper Lee</author>
        <year>1960</year>
        <price>15.99</price>
    </book>
</books>

 

이 경우, 다음 코드를 사용하여 books 요소의 모든 자식 요소를 반복하고 각 요소의 태그 이름과 내용을 출력할 수 있습니다. 즉, iter() 함수는 books 요소의 모든 자식 요소를 포함하여, 각 요소를 반복하며, 요소의 태그 이름과 내용을 출력합니다.

import xml.etree.ElementTree as ET

tree = ET.parse('books.xml')
root = tree.getroot()

for elem in root.iter():
    print(elem.tag, elem.text)
    
    
#books 

#book 
#title The Catcher in the Rye
#author J.D. Salinger
#year 1951
#price 19.99 

#book     
#title To Kill a Mockingbird
#author Harper Lee
#year 1960
#price 15.99

 

 

 


3.7 SubElement

 

SubElement 함수는 부모 요소에 새 하위 요소를 만듭니다. 이 함수는 부모 요소와 함께 하위 요소의 태그 이름을 전달받습니다. 또한, 하위 요소의 속성을 추가할 수도 있습니다.



아래 코드는 SubElement 함수를 사용하여 XML 문서를 만드는 코드입니다. 코드는 books 요소를 루트 요소로 하는 XML 문서를 만듭니다. books 요소의 하위 요소로 book1과 book2가 있으며, 각각의 요소는 id 속성과 title, author 요소를 가지고 있습니다. 이 코드에서는 SubElement 함수를 사용하여 book1과 book2 요소를 만들고, 이들 요소의 하위 요소로 title과 author를 만들었습니다. 마지막으로, XML 문서를 파일로 저장하려면 ElementTree 모듈의 write 함수를 사용합니다.

import xml.etree.ElementTree as ET

root = ET.Element("books")
book1 = ET.SubElement(root, "book", attrib={"id": "001"})
title1 = ET.SubElement(book1, "title")
title1.text = "Harry Potter and the Philosopher's Stone"
author1 = ET.SubElement(book1, "author")
author1.text = "J.K. Rowling"
book2 = ET.SubElement(root, "book", attrib={"id": "002"})
title2 = ET.SubElement(book2, "title")
title2.text = "The Hobbit"
author2 = ET.SubElement(book2, "author")
author2.text = "J.R.R. Tolkien"