JAVA_XML, JSON, CSV

JW__1.7·2022년 8월 15일
0

JAVA 공부일지

목록 보기
24/30

JSON (JavaScript Object Notation)

  • JSONObject 클래스 : { } 객체 (Map 기반) ★
  • JSONArray 클래스 : [ ] 배열 (List 기반)
  • {property : Value} = { key : Value }
  • 속성-값쌍 또는 키-값쌍으로 이루어진 개방형 표준 (Opened Standard) 데이터 포맷이다.
    • 이 값 하나 하나를 리터럴(literal), 키-값 쌍을 프로퍼티(Property)라 한다.
  • 브라우저/서버 통신을 위해, XML을 대체하는 주요 데이터 포맷으로 특히 인터넷에서 자료를 주고 받을 때 그 자료를 표현하는 방법이다.
  • 자료 종류에 제한이 없고, 컴퓨터 프로그램의 변수값을 표현하기 좋다.
  • 자바스크립트 언어로부터 파생되어 자바스크립트의 구문 형식을 따르지만, 실제로는 프로그래밍 언어나 플랫폼에 독립적이다.

JSON의 검증(Validation)

  • JSON 스키마는 3가지 검증(Validation) 과정을 거친다.
  1. 데이터 타입이 정확한지
  2. 필수로 받아야하는 데이터가 포함되어 있는지
  3. 데이터가 유효한 범위 내에 있는지
  • 이러한 검증 기준을 모두 키워드(keyword)를 이용해 직접 명시할 수 있다.

검증 키워드

  • 데이터에 대한 정보를 나타내는 검증 키워드

    • type : 데이터 타입
    • properties : 데이터 이름-값 쌍
    • required : 배열의 모든 요소를 프로퍼티로 가지고 있는지
    • minimum : 최소값 이상의 숫자만
    • maximum : 최대값 이상의 숫자만
    • multipleOf : 명시한 숫자의 배수만
    • maxLength : 명시한 최대 길이 이하의 문자열만
    • minLength : 명시한 최소 길이 이하의 문자열만
    • pattern : 명시한 정규 표현식
  • 스키마에 대한 정보를 나타내는 메타 데이터 키워드

    • title : 제목

    • description : 설명

    • default : 기본값

      JSON 예제 1

      import org.json.JSONArray;
      import org.json.JSONObject;
      

public class JSONWriter {
public static void ex1() {

	JSONObject obj1 = new JSONObject();
	obj1.put("name", "제임스");
	obj1.put("age", 30);
	
	JSONObject obj2 = new JSONObject();
	obj2.put("name", "에밀리");
	obj2.put("age", 20);
	
	JSONArray arr = new JSONArray();
	arr.put(obj1);
	arr.put(obj2);

	System.out.println(arr.toString());

}
}


```java
[{"name":"제임스","age":30},{"name":"에밀리","age":20}]

JSON 예제 2

import org.json.JSONObject;

public class JSONWriter {
	public static void ex2() {

		String str = "{\"name\":\"손석구\",\"man\":true,\"age\":45,\"height\":180}";
		
		JSONObject obj = new JSONObject(str);
		
		String name = obj.getString("name");
		boolean man = obj.getBoolean("man");
		int age = obj.getInt("age");
		double height = obj.getDouble("height");
		
		System.out.println(name);
		System.out.println(man);
		System.out.println(age);
		System.out.println(height);
	}
}
손석구
true
45
180.0

JSON vs XML

데이터를 나타낼 수 있는 방식은 여러가지가 있지만, 대표적인 것이 XML이고, 이후 가장 많이 사용되는 것이 아마도 JSON일 것이다.

  • JSON
    • 중괄호 { } 형식이며, 값을 ,로 나열해서 표현이 간단하다.
  • XML
    • 데이터 값 양쪽으로 태그 < >가 있다.

XML (Extensible Markup Language)

  • 확장 마크업 언어
  • 표준 마크업 언어인 HTML의 확장 버전
  • 정해진 <태그> 외 사용자 정의 태그 사용

XML 특징

  • 다른 목적의 마크업 언어를 만드는데 사용되는 다목적 마크업 언어이다.
  • 다른 시스템끼리 다양한 종류의 데이터를 손쉽게 교환할 수 있도록 해준다.
  • 새로운 태그를 만들어 추가해도 계속해서 동작하므로, 확장성이 좋다.
  • 데이터를 보여주지 않고, 데이터를 전달하고 저장하는 것만을 목적으로 한다.
  • 텍스트 데이터 형식의 언어로 모든 XML 문서는 유니코드 문자로만 이루어진다.

XML 요소

  • 시작태그와 종료태그로 한 쌍이 되어야 한다.
    <시작태그명> 요소내용 </종료태그명>

XML 선언

다음과 같이 자신에 대한 정보 일부를 선언하는 것으로 시작한다.

<?xml version="1.0" encoding="UTF-8" ?>

XML 문법

  • XML 문서는 매우 규칙적이라 예측이 가능한 구조이다.
  • 모든 XML 요소는 종료태그를 가져야 한다. (생략되면 오류 발생)
  • 대소문자를 구분하여 대소문자가 다르면 다른 요소로 인식한다.
  • 시작태그와 종료태그의 문자가 동일해야 한다. (앞에는 소문자, 뒤에는 대문자 X)
  • XML은 띄어쓰기를 인식한다.

XML 주석

  • <!-- 으로 시작해서 -->으로 끝난다.
  • 시작태그에는 느낌표가 있지만, 종료태그에는 느낌표가 없다.

JAVA로 XML 생성

XML 주요 메소드

  • Element createElement(String tagName) : Element 객체 생성
  • Attr createAttribute(String name) : Attribute 객체 생성
  • Text createTextNode(data) : Text 객체 생성
  • Comment createComment(data) : Comment 객체 생성
  • appendChild(노드명) : 노드명을 자식노드로 추가
  • setOutputProperty("설정할 대상" , "설정할 내용") : 출력할 때 추가적인 옵션을 설정할 수 있다.

Document 생성(문서 생성)

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.newDocument();
document.setXmlStandalone(true);	// standalone ="no" 제거

XML 구현 코드

import java.io.File;
import java.util.Arrays;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class XMLWriter {

	public static void main(String[] args) {
    	try {
			
			// Document 생성(문서 생성)
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
			DocumentBuilder builder = factory.newDocumentBuilder();
			Document document = builder.newDocument();
			document.setXmlStandalone(true);	// standalone ="no" 제거
			
            // Document에 products 태그 추가
			Element products = document.createElement("products");
			document.appendChild(products);
			
			List<String> product1 = Arrays.asList("100", "새우깡", "1500");
			List<String> product2 = Arrays.asList("101", "양파링", "2000");
			List<String> product3 = Arrays.asList("102", "홈런볼", "3000");
			
			List<List<String>> list = Arrays.asList(product1, product2, product3);
			
			for(List<String> line : list) {
				// 태그 생성
				Element product = document.createElement("product");
				Element number = document.createElement("number");
				number.setTextContent(line.get(0));
				Element name = document.createElement("name");
				name.setTextContent(line.get(1));
				Element price = document.createElement("price");
				price.setTextContent(line.get(2));
				
                // 태그 배치
				products.appendChild(product);
				product.appendChild(number);
				product.appendChild(name);
				product.appendChild(price);
			}
			
			// XML 생성
			TransformerFactory transformerFactory = TransformerFactory.newInstance();
			Transformer transformer = transformerFactory.newTransformer();
			transformer.setOutputProperty("encoding", "UTF-8");
			transformer.setOutputProperty("indent", "yes");	// indent 들여쓰기 , yes 하겠다
			transformer.setOutputProperty("doctype-public", "yes"); // document.setXmlStandalone
			
			Source source = new DOMSource(document);
			File file = new File("C:\\storage", "product.xml");
			StreamResult result = new StreamResult(file);
			
			transformer.transform(source, result);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}     
<?xml version="1.0" encoding="UTF-8"?>
<products>
		<product>
			<number>100</number>
			<name>새우깡</name>
			<price>1500</price>
		</product>
		<product>
			<number>101</number>
			<name>양파링</name>
			<price>2000</price>
		</product>
		<product>
			<number>102</number>
			<name>홈런볼</name>
			<price>3000</price>
		</product>
</products>

XML 문서 불러와서 읽기

Product 클래스를 생성해서 필드와 Getter/Setter를 넣어준다.

public class Product {
	
	private String number;
	private String name;
	private int price;
	
	public Product() {
		
	}

	public Product(String number, String name, int price) {
		super();
		this.number = number;
		this.name = name;
		this.price = price;
	}

	public String getNumber() {
		return number;
	}
	public void setNumber(String number) {
		this.number = number;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}

	@Override
	public String toString() {
		return "Product [number=" + number + ", name=" + name + ", price=" + price + "]";
	}
}

메인 XMLReader 메소드를 작성한다.

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class XMLReader {
	
	public static void main(String[] args) {
		
		try {
		
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		
		File file = new File("C:\\storage", "product.xml");
		Document document = builder.parse(file);	// product.xml을 파싱(분석)한 document 객체
		
		// 최상위 요소(root)
		Element root = document.getDocumentElement();
		System.out.println("최상위 요소 : " + root.getNodeName());
		
		List<Product> products = new ArrayList<Product>();
				
		// 최상위 요소의 자식 노드들
		NodeList nodeList = root.getChildNodes();
		for(int i = 0; i < nodeList.getLength(); i++) {
			Node node = nodeList.item(i);	// 줄바꿈(#text)과 <product> 태그로 구성
			if(node.getNodeType() == Node.ELEMENT_NODE) {	// 노드가 Element인가? _ 줄바꿈(#text) 제외되고, <product> 태그만 남는다.
				NodeList nodeList2 = node.getChildNodes();	// <product> 태그의 자식노드(<number>, <name>, <price> 태그)
				Product product = new Product();
				for(int j = 0; j < nodeList2.getLength(); j++) {
					Node node2 = nodeList2.item(j);
					if(node2.getNodeType() == Node.ELEMENT_NODE) {
						switch(node2.getNodeName()) {
						case "number" : product.setNumber(node2.getTextContent()); break;
						case "name" : product.setName(node2.getTextContent()); break;
						case "price" : product.setPrice(Integer.parseInt(node2.getTextContent())); break;
						}
					}
				}
				// ArrayList에 product 추가
				products.add(product);
			}
		}
		
		// ArrayList 확인
		for(Product product : products) {
			System.out.println(product);
		}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}

}
최상위 요소 : products
Product [number=100, name=새우깡, price=1500]
Product [number=101, name=양파링, price=2000]
Product [number=102, name=홈런볼, price=3000]

CSV

  • Comma Separate Values
  • 콤마로 분리된 값들
  • 확장자 .csv인 파일(기본 연결프로그램 : 엑셀, 메모장으로 오픈 가능)

CSV 예제

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;

public class CSVWriter {

	public static void main(String[] args) {

		// C:\storage\product.csv
		// 제품번호, 제품명, 가격\n
		// 100, 새우깡, 1500\n
		// 101, 양파링, 2000\n
		// 102, 홈런볼, 3000\n
		
		List<String> header = Arrays.asList("제품번호", "제품명", "가격");
		List<String> product1 = Arrays.asList("100", "새우깡", "1500");
		List<String> product2 = Arrays.asList("101", "양파링", "2000");
		List<String> product3 = Arrays.asList("102", "홈런볼", "3000");
		
		// 1차원 배열이 여러개 있는데 2차원 배열처럼
		List<List<String>> list = Arrays.asList(header, product1, product2, product3);
		
		File file = new File("C:\\storage", "product.csv");
	    FileWriter fw = null;
	    BufferedWriter bw = null;
	      
	      try {
	         fw = new FileWriter(file, StandardCharsets.UTF_8);
	         bw = new BufferedWriter(fw);
	         for(int i = 0, length = list.size(); i < length; i++) {
	 			List<String> line = list.get(i);
	 			// 마지막 요소면 Enter 아니면 (,)
	 			for(int j = 0, size = line.size(); j < size; j++) {
	 				if(j == size - 1) {
	 					bw.write(line.get(j) + "\n");
	 				} else {
	 					bw.write(line.get(j) + ",");
	 				}
	 			}
	         }
	      } catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if(bw != null) {
					bw.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}

0개의 댓글