일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- numpy
- ssh
- 코크리
- IVI
- Decision Boundary
- docker exec
- cocre
- Jupyter notebook
- 백신후원
- WSSS
- CellPin
- 기초확률론
- HookNet
- 티스토리챌린지
- 도커
- Multi-Resolution Networks for Semantic Segmentation in Whole Slide Images
- 프로그래머스
- 오블완
- GIT
- 사회조사분석사2급
- logistic regression
- 히비스서커스
- docker
- AIFFEL
- airflow
- vscode
- aiffel exploration
- docker attach
- Pull Request
- cs231n
- Today
- Total
히비스서커스의 블로그
[Python] python으로 xml파일 parsing 및 저장 (feat. findall) 본문
[Python] python으로 xml파일 parsing 및 저장 (feat. findall)
HibisCircus 2021. 10. 5. 20:18여러 장의 xml 파일에 특정 패턴을 수정하고자 하는 경우 직접 수정하는 것보다 코드로 함수를 만들어서 처리하는 것이 더 효율적일 것이다. 이번 포스팅으로 파이썬으로 xml파일을 parsing하고 저장하는 방법을 다뤄보고자 한다.
사용할 xml etree 라이브러리의 공식 API는 다음과 같다.
https://docs.python.org/ko/3/library/xml.etree.elementtree.html
먼저, 파일을 여는 방법은 다음과 같다.
import xml.etree.ElementTree as ET
xml_path = './xml_path/xml_file.xml'
xml_file = open(xml_path, 'rt', encoding='UTF8')
이제 본격적으로 xml 파일들을 수정해보자. 이번에 예시로 들 xml파일을 다음과 같다고 하자. 이 예시는 아래의 홈페이지에서 가져왔다.
https://www.w3schools.com/xml/xml_examples.asp
<breakfast_menu>
<food>
<name>Belgian Waffles</name>
<price>$5.95</price>
<description>Two of our famous Belgian Waffles with plenty of real maple syrup</description>
<calories>650</calories>
</food>
<food>
<name>Strawberry Belgian Waffles</name>
<price>$7.95</price>
<description>Light Belgian waffles covered with strawberries and whipped cream</description>
<calories>900</calories>
</food>
<food>
<name>Berry-Berry Belgian Waffles</name>
<price>$8.95</price>
<description>Light Belgian waffles covered with an assortment of fresh berries and whipped cream</description>
<calories>900</calories>
</food>
<food>
<name>French Toast</name>
<price>$4.50</price>
<description>Thick slices made from our homemade sourdough bread</description>
<calories>600</calories>
</food>
<food>
<name>Homestyle Breakfast</name>
<price>$6.95</price>
<description>Two eggs, bacon or sausage, toast, and our ever-popular hash browns</description>
<calories>950</calories>
</food>
</breakfast_menu>
아침식사 메뉴판인데 Belgian Waffles이 적힌 food들의 칸은 모두 삭제하고 싶다고 해보자.
먼저, parse와 getroot를 이용하여 파일 내용들을 가져와보자.
anno = ET.parse(xml_file)
breakfast_menu = anno.getroot()
다음으로, iter를 사용하여 name이 있는 줄들을 모두 불러오게 하자. 이때, food들의 칸을 모두 지워하여 하므로 zip을 통해서 같이 불러오자. 모든 food들 안에 name이 한개 씩만 있으므로 가능하다. for 문을 통해 지워보자.
for i, (name, food) in enumerate(zip(breakfast_menu.iter('name'), breakfast_menu)):
if 'Belgian Waffles' in name.text:
breakfast_menu.remove(food)
이와 같이 코드를 짤 경우 문제가 생긴다. 바로 for문을 돌면서 리스트를 지워버리므로 한 번만 돌릴 시 Belgian Waffles와 Berry-Berry Belgian Waffles만 지워지게 된다. 2번째인 Strawberry Belgian Waffles는 리스트에서 Belgian Waffles를 지워버림과 동시에 1번째가 되고 for문을 2번째를 불러오기 때문에 3번째인 Berry-Berry Belgian Waffles만 불러오기 때문이다. 따라서, 원하는 목적을 위해서는 몇 번 반복해서 코드를 돌려주어야 한다.
이를 방지하기 위한 방법이 친절하게도 etree 안에 있다. 바로 findall 함수를 이용하는 것이다. 이는 리스트들을 미리 수집한 후 for문을 돌릴 수 있기 때문에 다음과 같은 상황을 방지 할 수 있다. findall을 사용한 코드는 다음과 같다.
for food in breakfast_menu.findall('food'):
name = food.find('name').text
if 'Belgian Waffles' in name:
breakfast_menu.remove(food)
이를 활용하면 한 번의 코드 실행으로 원하는 목적을 이룰 수 있다.
다음으로 파일을 저장하는 코드이다.
anno.write(targetDir)
이를 여러 파일에 대해 실행하고 싶을 경우 glob를 사용하여 다음과 같이 코드를 활용하면 된다.
import os
import xml.etree.ElementTree as ET
import glob
for targetDir in sorted(glob.glob('./xml_file_list/*.xml')) :
print('======'*10, targetDir, '======'*10, sep='\n')
targetXML = open(targetDir, 'rt', encoding='UTF8')
anno = ET.parse(targetXML)
breakfast_menu = anno.getroot()
for food in breakfast_menu.findall('food'):
name = food.find('name').text
if 'Belgian Waffles' in name:
print('found!')
breakfast_menu.remove(food)
anno.write(targetDir)
이제는 파이썬에서 xml파일을 손쉽게 수정해보자!
2021.12.17 오타수정
-히비스서커스-
'Programming > Python' 카테고리의 다른 글
[Pytorch] AttributeError: 'DataParallel' object has no attribute 'predict' (0) | 2021.10.08 |
---|---|
[Pytorch] RuntimeError: Input type (torch.cuda.ByteTensor) and weight type (torch.cuda.FloatTensor) should be the same (0) | 2021.10.07 |
[Numpy] numpy로 이미지 처리하기 3 (2) | 2021.09.09 |
[Numpy] numpy로 이미지 처리하기 2 (0) | 2021.09.09 |
[Python] 한 줄 코드 및 GPU 분산처리 코드 (0) | 2021.08.26 |