김원경 11월 3일, 2021에 포스트됨 공유하기 11월 3일, 2021에 포스트됨 이 글에서는 최근 많이 사용되는 JSON에 대해서 알아보고 델파이에서 JSON 데이터를 작성하거나 JSON데이터를 파싱(읽기) 하는 방법등에 대해서 정리해 보았다. JSON이란? JavaScript Object Notation의 약자로 데이터를 저장하거나 전송할 때 많이 사용되는 경량의 DATA 교환 형식이다. JSON 표현식은 사람과 기계 모두 이해하기 쉬우며 용량이 작아서, 최근에는 JSON이 XML을 대체해서 데이터 전송 등에 많이 사용한다. JSON은 데이터 포맷일 뿐이며 어떠한 통신 방법도, 프로그래밍 문법도 아닌 단순히 데이터를 표시하는 표현 방법일 뿐이다. JSON 특징 서버와 클라이언트 간의 교류에서 일반적으로 많이 사용된다. 다른 프로그래밍 언어를 이용해서도 쉽게 만들 수 있다. 특정 언어에 종속되지 않으며, 대부분의 프로그래밍 언어에서 JSON 포맷의 데이터를 핸들링 할 수 있는 라이브러리, 클래스들을 제공한다. JSON 문법 JSON 형식은 key/value가 존재할 수 있으며 key값이나 문자열은 항상 쌍 따옴표를 이용하여 표기한다. 개체, 배열 등의 표기를 사용할 수 있다. JSON형식에서는 null, number, string, array, object, boolean을 사용할 수 있다. JSON 형식 name-value형식의 쌍 값들의 순서화된 리스트 형식 델파이에서 사용되는 JSON 클래스들 아래 표에 표시된 JSON 데이터를 표현하기 위한 클래스들은 system.json에 정의 되어 있다. (TJSONReader, TJSONWriter 클래스는 뒤에서 설명) JSON 데이터 작성(쓰기) 아래 화면과 동일한 JSON 데이터를 작성하기 위해 각각 다른 방식으로 구현한 예제이다. 1. JSON Objects 사용 procedure TForm1.Button1Click(Sender: TObject); var JSONColor : TJSONObject; JSONObject : TJSONObject; JSONArray : TJSONArray; begin try JSONColor := TJSONObject.Create; JSONColor.AddPair('name', 'red'); JSONColor.AddPair('hex', '#f00'); JSONArray := TJSONArray.Create; JSONArray.Add(JSONColor); JSONObject := TJSONObject.Create; JSONObject.AddPair('colors', JSONArray); Memo1.Text := JSONObject.ToString; finally JSONObject.Free; end; end; 2. TJSonWriter 사용 TJSONWriter : JSON 데이터를 직렬화하는 논리를 제공하는 기본 클래스. TJsonTextWriter : JSON 콘텐츠를 작성하기 위해 TJsonWriter에서 확장된 클래스이다. TJsonTextWriter 는 잘못된 JSON에 대한 오류 검사를 제공한다. TStringWriter : 문자열에 쓰는 TTextWriter를 구현한다. 작성 중인 문자열은 TStringBuilder 인스턴스를 사용하여 작성된다. JSON 데이터를 작성하려면: 지정된 텍스트 작성기(TextWriter)에 데이터를 쓰는 JSONWriter를 작성한다. JSON 토큰이 생성될 적절한 Writer 메소드을 순차적으로 호출한다. 예를 들어 WriteStartObject를 호출하여 JSON 의 오브젝트의 시작 부분을 쓴다. procedure TForm1.Button2Click(Sender: TObject); var writer: TJsonWriter; StringWriter: TStringWriter; begin try StringWriter := TStringWriter.Create; Writer := TJsonTextWriter.Create( StringWriter ); Writer.WriteStartObject; Writer.WritePropertyName('colors'); Writer.WriteStartArray; Writer.WriteStartObject; Writer.WritePropertyName('name'); Writer.WriteValue('red'); Writer.WritePropertyName('hex'); Writer.WriteValue('#f00'); Writer.WriteEndObject; Writer.WriteEndArray; Writer.WriteEndObject; memo2.Text := Stringwriter.ToString; finally StringWriter.Free; Writer.Free; end; end; 3. TJSONObjectBuilder 사용 TJSONObjectBuilder : JSON 오브젝트를 작성하기 위한 다양한 인터페이스를 제공하는 JSONWriter 래퍼 클래스. TJsonTextWriter는 다음과 같은 몇 가지 추가 기능도 제공한다. 포맷 지정은 JSON 텍스트의 형식을 지정하는 방법을 나타낸다. 들여쓰기로 설정하면 결과는 들여쓰기가 있는 읽기 쉬운 JSON 데이터가 된다. procedure TForm1.Button3Click(Sender: TObject); var Builder : TJSONObjectBuilder; writer: TJsontextWriter; StringWriter: TStringWriter; StringBuilder: TStringBuilder; begin try StringBuilder := TStringBuilder.Create; StringWriter := TStringWriter.Create(StringBuilder); Writer := TJsonTextWriter.Create(StringWriter); Writer.Formatting := TJsonFormatting.Indented; Builder := TJSONObjectBuilder.Create(Writer); Builder .BeginObject .BeginArray('colors') .BeginObject .Add('name', 'red') .Add('hex', '#f00') .EndObject .EndArray .EndObject; memo3.Text := Stringbuilder.tostring; finally Builder.Free; writer.Free; StringWriter.Free; StringBuilder.Free; end; end; 그 외의 방법으로 Firedac 컴포넌트인 TFDBatchMove, TFDBatchMoveJsonWriter를 사용하여 텍스트(TFDBatchMoveTextReader 컴포넌트 사용), 데이터셋(TFDBatchMoveDataSetReader 컴포넌트 사용)을 Json 데이터로 생성할 수 있다. 아래 샘플에서는 C:\Users\Public\Documents\Embarcadero\Studio\22.0\Samples\Data 폴더에 있는 xml 데이터를 데이터셋에 로드하여 사용하였음(* 데이터베이스 사용하지 않고 테스트 할 수 있음) TFDBatchMove를 이용한 샘플 : JSON_BatchMove.zip JSON 파싱(읽기) 위에서 작성한 JSON 데이터를 아래 화면과 같이 다른 방법을 사용하여 파싱하는 예이다. 1. JSON Objects 사용 procedure TForm1.Button4Click(Sender: TObject); var JSONValue : TJSONvalue; begin JSONValue := TJSONObject.ParseJSONValue('{"colors":[{"name":"red", "hex":"#f00"}]}'); try Memo4.Lines.Add('READER:'); if JSONValue is TJSONArray then //... else if JSONVAlue is TJSONObject then Memo4.Lines.Add('colors'); Memo4.Lines.Add('name: '+ JSONValue.GetValue<string>('colors[0].name')); Memo4.Lines.Add('hex: '+ JSONValue.GetValue<string>('colors[0].hex')); finally JSONVAlue.Free; end; end; 2. TJSonReader 사용 TJSONReader : JSON 또는 유사한 형식의 직렬화된 데이터를 읽을 수 있는 기본 클래스. 이 클래스를 사용하기 위해서는 uses절에 System.JSON.Readers을 추가해야 한다. TJsonTextReader : JSON 형식으로 직렬화된 데이터를 읽는 클래스. TStringReader : 문자열에 대한 리더 클래스 데이터를 읽으려면: 텍스트 리더에서 데이터를 읽는 JSONReader 를 생성한다. 리더가 입력 데이터의 첫 번째 JSON 토큰으로 이동하도록 Read를 호출한다. TokenType은 토큰의 유형을 나타낸다. 또한 IsPrimitiveToken, IsStartToken 또는 IsEndToken을 사용하여 토큰 유형이 특정 토큰 유형 집합에 속하는지 여부를 확인할 수 있다. Value 속성은 토큰 값에 대한 액세스를 제공한다. 예를 들어 TokenType이 PropertyName이면 Value.AsString을 호출하여 속성 이름에 액세스 한다. CurrentState는 리더 상태를 나타낸다. LineNumber 및 LinePosition은 리더가 있는 입력 데이터 내 위치를 나타낸다. procedure TForm1.Button5Click(Sender: TObject); var LStringReader : TStringReader; LJsonTextReader : TJsonTextReader; begin LStringReader := TStringReader.Create('{"colors":[{"name":"red", "hex":"#f00"}]}'); LJsonTextReader:= TJsonTextReader.Create(LStringReader); try while LJsonTextReader.read do case LJsonTextReader.TokenType of TJsonToken.PropertyName: Memo5.Lines.Add(LJsonTextReader.Value.AsString); TJsonToken.String: Memo5.Lines[Memo5.Lines.Count-1] := Memo5.Lines[Memo5.Lines.Count-1] + ': ' +LJsonTextReader.Value.AsString; end; finally LStringReader.free; LJsonTextReader.Free; end; end; 3. TJONIterator 사용 JSON 리더가 제공하는 콘텐츠를 반복할 수 있다. lterrator는 JSON 리더와 유사하지만 몇 가지 추가 기능을 제공하고 약간 다르게 작동한다. 예를 들어: Lterator는 모든 토큰을 통과할 필요가 없다. 특정 배열 또는 개체 항목으로 이동하거나, 배열 및 개체의 일부를 건너뛰거나, 전체 배열 및 개체를 건너뛸 수 있다. lterrator 배열 또는 개체 값의 토큰에 있으면 해당 값과 일치하는 배열 인덱스 또는 개체 키를 읽을 수 있다. 해당 정보를 별도로 추적할 필요가 없다. terrator는 오브젝트 키에서 멈추지 않는다. 대신 키를 건너뛰고 해당 값의 토큰으로 반복한다. iterator의 Key 속성에서 Value 토큰의 키를 읽을 수 있다. JSONReader 의 내용을 반복하려면: JSON Reader에서 데이터를 읽는 JSON Lterator를 생성한다. Next메소드를 호출하면 리더가 입력 데이터의 첫 번째 JSON 토큰으로 이동한다. 유형은 토큰의 유형을 나타냅니다. 배열을 반복하는 경우 인덱스를 사용하여 현재 토큰의 인덱스를 가져온다. 오브젝트를 반복하는 경우 Key를 사용하여 현재 토큰의 키를 가져온다. Lterator의 값 속성 중 하나를 사용하여 현재 토큰의 값에 액세스한다. 예를 들어 유형이 부울이면 AsBoolean을 호출하여 현재 토큰의 부울 값에 액세스한다. Next를 계속 호출하여 입력 데이터의 모든 JSON 토큰을 살펴본다. Next는 입력 데이터의 끝에 도달하면 False를 반환한다. Recurse(되감기)를 사용하여 Lterator를 입력 데이터의 시작 부분으로 다시 이동할 수 있다. procedure TForm1.Button6Click(Sender: TObject); var LStringReader : TStringReader; LJsonTextReader : TJsonTextReader; LIterator : TJSONIterator; begin LStringReader := TStringReader.Create('{"colors":[{"name":"red", "hex":"#f00"}]}'); LJsonTextReader := TJsonTextReader.Create(LStringReader); LIterator := TJSONIterator.Create(LJsonTextReader); try LIterator.Next; Memo6.Lines.Add(LIterator.Key); LIterator.Recurse; LIterator.Next; LIterator.Recurse; LIterator.Next; Memo6.Lines.Add(LIterator.Key +': '+ LIterator.AsString); LIterator.Next; Memo6.Lines.Add(LIterator.Key +': '+ LIterator.AsString); finally LStringReader.Free; LJsonTextReader.Free; LIterator.Free; end; end; 샘플 소스 : JSON_Reader_Writer.zip 인용하기 이 댓글 링크 다른 사이트에 공유하기 더 많은 공유 선택 사항
Miniuser 11월 16일, 2022에 포스트됨 공유하기 11월 16일, 2022에 포스트됨 On 2021. 11. 3. at 오후 5시 5분, 김원경 said: JSON Objects 사용 파싱할때 에 기본값을 설정하려면 (TJSONObject).GetValue<String>('KeyName', 'DefaultValue') 이런식으로 2번째 파라미터에 값을 넣어주시면 됩니다. 간혹 오타나, 누락된 값을 파싱하려고 하면 오류가 발생하니, JSON 작업시 참고해주세요~ ※ 수정해야 하는 부분 있으면 댓글이나 쪽지 부탁드립니다! 인용하기 이 댓글 링크 다른 사이트에 공유하기 더 많은 공유 선택 사항
Recommended Posts
이 토의에 참여하세요
지금 바로 의견을 남길 수 있습니다. 그리고 나서 가입해도 됩니다. 이미 회원이라면, 지금 로그인하고 본인 계정으로 의견을 남기세요.