이 포스트는 파이썬으로 XML 파싱하기 포스트를 바탕으로 다시 포스팅합니다.
여기서 바뀐 점은 다음과 같습니다.
- 문자열로부터 직접 XML 문서를 받아들이는 방식
.find()
메소드 사용으로 더 간편하게 찾는 방식
코딩해 보면 다음과 같이 됩니다.
xmlstr = """<?xml version="1.0"?> <girlgroup> <name alias="GFRIEND">여자친구</name> <members> <member>소원</member> <member>예린</member> <member>은하</member> <member>유주</member> <member>신비</member> <member>엄지</member> </members> <albums> <album order="EP 1집">Season of Glass</album> <album order="EP 2집">Flower Bud</album> <album order="EP 3집">Snowflake</album> <album order="정규 1집">LOL</album> <album order="EP 4집">THE AWAKENING</album> </albums> </girlgroup> """
위와 같이 XML 문서를 저장해 놓은 문자열이 있다고 했을 때
from lxml import etree # Empty array members = [] albums = [] # Load XML root = etree.fromstring(xmlstr) gname = root.find("name").text for x_member in root.find("members"): members.append(x_member.text) for x_album in root.find("albums"): albums.append([x_album.get("order"), x_album.text]) # Print print("걸그룹 %s에 대한 정보는 다음과 같습니다:" % gname, end="\n\n") print(" 멤버: ", end="") print(", ".join(members)) print("\n [앨범 목록]") for album in albums: print(" * %s: %s" % (album[0], album[1]) )
이렇게 코딩합니다. 기본적으로는 파이썬으로 XML 파싱하기 포스트와 같지만 차이가 있습니다.
우선, 28번 줄에서 XML을 받아들이는데 파일이 아닌 문자열로 받아들입니다. 이 때는 etree.parse()
대신 etree.fromstring()
메소드를 사용합니다. 이 경우 .getroot()
메소드를 거치지 않고 바로 루트 요소로 변환됩니다.
30번 줄은 하위 요소들을 살피면서 .tag
프로퍼티로 태그 이름을 찾지 않고 그 대신 .find()
메소드를 써서 태그 이름을 찾습니다. 그룹 이름이 적혀 있는 <name>
태그를 찾아 그 뒤에 .text
프로퍼티를 써서 태그 안의 텍스트를 변환합니다.
31번 줄과 33번 줄도 같은 방식입니다. 다만 find 메소드 뒤에 아무 프로퍼티도 쓰지 않으면 그 태그 밑의 요소들을 배열 형식으로 돌려주게 됩니다.
그 다음은 파이썬으로 XML 파싱하기 포스트와 같습니다.
걸그룹 여자친구에 대한 정보는 다음과 같습니다: 멤버: 소원, 예린, 은하, 유주, 신비, 엄지 [앨범 목록] * EP 1집: Season of Glass * EP 2집: Flower Bud * EP 3집: Snowflake * 정규 1집: LOL * EP 4집: THE AWAKENING
이와 같이 됩니다.
참고사항
.find()
메소드는 해당 태그의 바로 아랫 단계에 있는 태그만 찾아집니다.
이 예제에서는root
형식으로 찾으면.find("member") <members>
밑의<member>
태그가 탐색되지 않으므로members = root
|.find("members") member
또는.find("member") root
처럼 한 다리 거쳐가는 방식을 사용해야 합니다..find("members") .find("member") .find()
메소드를 쓰면 해당 이름을 가진 태그가 둘 이상일 경우 그 중 첫 번째 태그만 탐색됩니다. 예를 들어, 바로 위처럼root
코드를 쓸 경우 맨 첫 번째.find("members") .find("member") .text <member>
태그에 있는 ‘소원’이라는 값이 추출됩니다.- 만약 같은 이름의 태그가 있을 때 맨 첫 번째 태그만이 아니라 그 이름의 모든 태그를 배열로 추출하고자 할 때는
.findall()
메소드를 씁니다. 예를 들어,root
코드를 쓸 경우.find("members") .findall("member")[1].text <member>
태그가 배열화되어 그 중 두 번째 태그에 있는 ‘예린’이라는 값이 추출됩니다.