23. XML 파일 파싱
in Study on R Programming
Overview
R에서 XML 파일을 파싱하여 R의 데이터 프레임으로 변경하는 방법을 알아본다.
예제 파일 : jsonexfile.zip
JSON
XML(Extensible Markup Language)은 W3C에서 개발된, 다른 특수한 목적을 갖는 마크업 언어를 만드는데 사용하도록 권장하는 다목적 마크업 언어이다.
XML은 주로 다른 종류의 시스템, 특히 인터넷에 연결된 시스템끼리 데이터를 쉽게 주고 받을 수 있게 하여 HTML의 한계를 극복할 목적으로 만들어졌다.
JSON 파일의 구조
XML 파일을 R으로 가져오기
XML 파일을 R으로 가져오기 위해 xml2
패키지를 사용하며, read_xml
함수를 이용하여 데이터를 가져올 수 있다.
예제를 통해 XML의 데이터를 가져오는 방법을 알아본다.
예제
# install.packages("xml2")
# install.packages("tidyverse")
library(xml2)
library(dplyr)
library(stringr)
library(tidyverse)
xPath01 <- 'breakfast.xml'
# read_xml 함수를 이용한 file read
xData01 <- read_xml(xPath01)
# raw xml 의 구조 파악
mode(xData01)
class(xData01)
xData01
# raw xml 의 자식노드의 구조 파악
f_node <- xml_children(xData01)
mode(f_node)
class(f_node)
# "xml_nodeset"
# node 의 1번째 자식에 접근
f_node[1]
# './*' : 현 위치의 모든 객체
# xml_find_all(x, y) : x번째 항목의 y항목을 모두 찾기
xml_find_all(f_node[1], './*')
# pipe 연산자 사용하여 같은 값 도출 가능
f_node[2] %>% xml_find_all('./*')
# <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>
mExtract <- function(x) {
# tmp_row : x 번째 행 데이터
# tmp_row 에 자식노드 다 가져옴
tmp_row <- xml_find_all(f_node[x], './*')
tibble(
idx = x,
# tag
# xml_name() : tag name 가져오기
key = tmp_row %>% xml_name(),
# value
# xml_text() : tag안에 있는 값을 가져오기
# trim 하는 이유 : white char(\n etc.) 없애기 위함
value = str_trim(tmp_row %>% xml_text())
) %>% return() # pipe 연산자로 리턴
}
seq(f_node)
# lapply : seq 를 이용한 for 문과 비슷한 작용
# lapply(seq, func)
mTibble <- lapply(seq(f_node), mExtract)
mTibble
mode(mTibble)
class(mTibble)
str(mTibble)
summary(mTibble)
# bind_rows() : table 로 묶어주는 함수
# spread(key, value) : 키값을 colnames로, value 값을 내용으로 펼쳐준다.
data01 <- mTibble %>% bind_rows() %>% spread(key, value)
data01
data02 <- mTibble %>% bind_rows() %>% spread(key, value) %>% select(f_node %>% xml_children() %>% xml_name() %>% unique())
mode(data02)
class(data02)
str(data02)
data02
write.csv(data02, 'breakfastXML.csv')