[Flora] Xml 데이터 가져오기, Json 형태로 바꾸어 화면에 출력하기

2023. 9. 17. 20:00프로젝트

# .env 파일 생성하기

react에서 .env 파일을 사용하기 위해서는 react 프로젝트 최상위 루트에 dotenv 라이브러리를 설치해야합니다.

  • npm install dotenv

dotenv는 환경변수를 .env 파일에 저장시켜주며 process.env로 로드하며, 특히 .env 파일에는 사용자에게 공개되면 안되는 값들을 변수로 저장하여 사용합니다.

package.json파일과 같은 경로에 .env 로 새로운 파일을 생성해주고 react에서는 앞에 'REACT_APP_'을 붙여주어야 인식이 가능합니다.

  • REACT_APP_변수이름=값

저는 변수이름 'API_KEY'로 설정하였고 뒤에 API 신청 후 발급받은 인코딩 키를 적어주었습니다.

  • REACT_APP_API_KEY=인코딩된 키 값

 

# API 호출하여 JSON 형태로 변환

데이터, 로딩 상태, 에러 상태, 요청 URL, 불러올 인코딩 키 값을 저장할 변수들을 생성합니다.

요청 URL은 전역에서 사용되기위해 전역 변수로 선언해줍니다!!!

import { useEffect, useState } from "react";
const URL = "http://apis.data.go.kr/1390804/NihhsTodayFlowerInfo01/selectTodayFlowerView01";

export default function Main() {
    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null);
    const key = process.env.REACT_APP_API_KEY;
    return(
        <div></div>
    );
}

API를 받아오기위한 데이터 수신방식은 GET 방식이고 axios 모듈을 사용합니다.

  • npm install axios

파라미터는 개발자가 원하는 페이지의 목적에 바꾸어 수정하여 사용합니다.

저는 일단 첫 번째 데이터의 전체목록을 불러오겠습니다.

import axios from "axios";
import { useEffect, useState } from "react";

const URL = "http://apis.data.go.kr/1390804/NihhsTodayFlowerInfo01/selectTodayFlowerView01";

export default function Main() {
    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null);
    const key = process.env.REACT_APP_API_KEY; // .env파일에 저장해둔 API 서비스 키

    const fetchData = async () => {
        try {
            setError(null);
            setData(null);
            setLoading(true);

            const response = await axios.get(URL, {
                params: {
                    serviceKey: decodeURIComponent(key), // 인코딩 재발을 방지한 디코딩
                    dataNo: 1, // 요청할 파라미터
                },
            });
            setData(response);
        } catch (e) {
            setError(e);
        }
        setLoading(false);
    };

    useEffect(() => {
        fetchData();
    }, []);

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;
    if (!data) return null;

    return(
        <div></div>
    );
}

※ 우리가 받아온 공용 API는 인코딩되어져 있는 값이기 떄문에 위의 decodeURIComponent 함수를 사용하지 않는 다면 SERVICE KEY IS NOT REGISTERED ERROR 가 발생할 수 있다.

 

console.log로 response를 출력해보면 xml 형식의 데이터가 넘어오신것을 볼 수 있습니다.

실제 페이지에서 개발자모드(F12)에 들어가보면 아래와 같이 정보를 받아온 것을 확인할 수 있습니다.

하지만, 우리가 원하는 것은 data안의 각각의 값 중 꽃이름, 꽃말 등의 필요한 정보만을 추출해야 하므로 JSON 파일로 바꿔주어 값에 접근해야합니다.

이를 위해, 저는 xml2js 라이브러리를 설치하여 사용하였습니다.

  • npm install react-native-xml2js

다음은 실제 xml2js를 적용한 코드입니다!

// XML 데이터를 JSON으로 변환
xml2js.parseString(response.data, (err, result) => {
    if (err) {
        throw err;
    }
	const jsonData = JSON.parse(result);
	setData(jsonData);
});

제가 가져온 데이터는 여기서 문제가 발생하였습니다...

데이터의 형식이 json 형식과 맞지않다는것!!! 따라서, 일단 xml 파일을 문자열로 바꾸고 json파일 형식에 맞추어 앞뒤로 슬라이싱을 사용하였습니다.

xml2js.parseString(response.data, (err, result) => {
    if (err) {
        throw err;
    }
    const jsonData = JSON.stringify(result); // xml 파일을 문자열로 저장
    var data1 = jsonData.slice(21); // 앞에서 21자 슬라이싱
    var data2 = data1.slice(0, -3); // 뒤에서 3자 슬라이싱
    const result_data = JSON.parse(data2); // JSON파일로 변환

    console.log(result_data.result[0].flowNm); // 실제 데이터에 접근 후 출력
    setData(result_data.result[0]);
});

개발자모드에서 콘솔을 확인해보니

실제로 원하는 데이터가 넘어온 것을 확인할 수 있었습니다!!

 

# 전체 코드

그럼 마지막으로 전체코드입니다.

import axios from "axios";
import { useEffect, useState } from "react";
import xml2js from "react-native-xml2js";

const URL = "http://apis.data.go.kr/1390804/NihhsTodayFlowerInfo01/selectTodayFlowerView01";
export default function Main() {
    const [data, setData] = useState(null);
    const [loading, setLoading] = useState(false);
    const [error, setError] = useState(null);
    const key = process.env.REACT_APP_API_KEY;

    const fetchData = async () => {
        try {
            setError(null);
            setData(null);
            setLoading(true);

            const response = await axios.get(URL, {
                params: {
                    serviceKey: decodeURIComponent(key),
                    dataNo: 1,
                },
            });

            // XML 데이터를 JSON으로 변환
            xml2js.parseString(response.data, (err, result) => {
                if (err) {
                    throw err;
                }
                const jsonData = JSON.stringify(result);
                var data1 = jsonData.slice(21);
                var data2 = data1.slice(0, -3);
                const result_data = JSON.parse(data2);

                console.log(result_data.result[0].flowNm);
                setData(result_data.result[0]);
            });
        } catch (e) {
            setError(e);
        }
        setLoading(false);
    };

    useEffect(() => {
        fetchData();
    }, []);

    if (loading) return <div>Loading...</div>;
    if (error) return <div>Error: {error.message}</div>;
    if (!data) return null;

    return (
        <div>
            <div>
                <h1>{data.flowNm}</h1>
                <p><strong>학명:</strong> {data.fSctNm}</p>
                <p><strong>영문 이름:</strong> {data.fEngNm}</p>
                <p><strong>꽃 언어:</strong> {data.flowLang}</p>
                <p><strong>설명:</strong> {data.fContent}</p>
                <p><strong>용도:</strong> {data.fUse}</p>
                <p><strong>성장:</strong> {data.fGrow}</p>
                <p><strong>품종:</strong> {data.fType}</p>
                <img src={data.imgUrl1} alt="꽃 이미지 1" />
                <img src={data.imgUrl2} alt="꽃 이미지 2" />
                <img src={data.imgUrl3} alt="꽃 이미지 3" />
                <p><strong>출처:</strong> {data.publishOrg}</p>
            </div>
        </div>
    );
}

 

'프로젝트' 카테고리의 다른 글

[Flora] OpenAPI 사용하기  (0) 2023.09.14
[Flora] 꽃 추천 프로젝트 - 프로젝트 개요  (0) 2023.09.13