Sign in Join
Wiki copytemporary

XML Tutorial/ko: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: XML Tutorial/ko

OldNewLine
1+## 소개
2+
3+확장 가능한 마크업 언어는 [W3C](http://www.w3.org/)가 추천하는 언어로서 다른 시스템간에 정보를 교환하기 위해 만들어 졌다. 텍스트 기반으로 정보를 저장한다. 현대의 XHTML 같은 데이터 교환 언어와 대부분의 웹서비스 기술은 XML에 기초를 두고 있다.
4+
5+현대 프리 파스칼에서 XML을 위해 지원하는 유닛의 셋이 있다. 이러한 유닛은 "XMLRead", "XMLWrite" 및 "DOM" 이라고 불리며 이들은 프리파스칼 컴파일러상의 프리컴포넌트 라이브러리(FCL)의 일부이다. FCL은 현재(2005년 10월) 문서화 되어있지 않으므로 이 간단한 튜토리얼은 이와같은 유닛을 통해 XML에 접근한다는 것을 소개하고자 함이다.
6+
7+XML DOM(Document Object Model) 은 표준화된 객체의 집합으로다른 언어와 기종을 사용해서 유사한 인터페이스를 제공해 준다. 표준은 객체의 메써드, 프로퍼티 및 다른 인터페이스 부분만을 명기할 뿐이며, 다른 언어에서 구현하는 것은 자유스럽게 놔둔다. FCL은 현재 [XML DOM 2.0](http://www.w3.org/TR/2000/REC-DOM-Level-2-Core-20001113/) 을 모두 지원하고 [XML DOM 3.0](http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/) 중 [[dom|이곳에]] 리스트한 서브셋을 지원한다.
8+
9+## 유용한 예제
10+
11+아래에 점점 복잡해지는 XML 데이터 조작에 관한 리스트가 있다.
12+
13+### uses 절에 있는 유닛: Unicode 또는 Ansi
14+
15+FPC는 ansi로 인코딩 된 루틴을 이용할 수 있는 XML 유닛을 포함하므로 각 플랫폼에의 인코딩은 달라질 수 있으며 Unicode가 아닐 수 있다. 라자루스는 LaxUtils 패키지에 모든 플랫폼에서 UTF-8 유니코드를 완전히 지원하는 각기 다른 XML 유닛의 서브셋을 가진다. 이 유닛은 상호 호환성이 있어 uses 절만 바꿈으로써 다른 것으로 바꿀 수 있다.
16+
17+시스템 인코딩에서 인코딩 된 문자열을 사용하는 FPC XML 유닛은 다음과 같다: DOM, XMLRead, XMLWrite, XMLCfg, XMLUtils, XMLStreaming.
18+
19+완전히 UTF-8 유니코드를 지원하는 라지루스 XML을 지원하는 유닛은 다음과 같다: laz2_DOM, laz2_XMLRead, laz2_XMLWrite, laz2_XMLCfg, laz2_XMLUtils, laz_XMLStreaming.
20+
21+모든 예제에서 위의 모든 유닛을 포함하는 것은 아니다.
22+
23+### 텍스트 노드 읽기
24+
25+델파이 프로그래머를 위해: TXMLDocument로 작업한다면 Node사이에 있는 텍스트는 분리된 TEXT Node로 고려해야한다는 것을 명심해야 한다. 그 결과 노드의 텍스트 값은 분리된 노으로서 접근해야 한다. 또한, **TextContent** 프로퍼티는 주어진 한개( 같이 연결된)의 하부에 있는 모든 텍스트 노드의 내용을 받을 수 있다.
26+
27+**ReadXMLFile** 프로시져는 항상 새로운 **TXMLDocument** 를 생성하므로 직접 생성할 필요가 없다. 그러나 이럴 경우 반드시 **Free** 를 콜하여 도큐먼트를 해제하여야 한다는 것을 명심하라.
28+
29+예를 들어, 다음 XML을 생각해보자:
30+
31+``` xml
32+ <?xml version="1.0"?>
33+ <request>
34+ <request_type>PUT_FILE</request_type>
35+ <username>123</username>
36+ <password>abc</password>
37+ </request>
38+```
39+
40+다음 코드는 텍스트 노드에서 값을 검색하는 경우의 올바른 방법과 틀린 방법을 보여 준다:
41+
42+``` pascal
43+ var
44+ PassNode: TDOMNode;
45+ Doc: TXMLDocument;
46+ begin
47+ // 디스크에서 xml 파일을 읽는다
48+ ReadXMLFile(Doc, 'c:\xmlfiles\test.xml');
49+ // "password"를 가져온다
50+ PassNode := Doc.DocumentElement.FindNode('password');
51+ // 선택된 노드의 값을 쓴다
52+ WriteLn(PassNode.NodeValue); // will be blank
53+ // 노드의 텍스트는 실제는 분리왼 자식 노드이다
54+ WriteLn(PassNode.FirstChild.NodeValue); // correctly prints "abc"
55+ // 다른 방법으로
56+ WriteLn(PassNode.TextContent);
57+ // 마지막으로 도큐먼트를 해제한다.
58+ Doc.Free;
59+end;
60+```
61+
62+### 노드의 이름을 프린드 하기
63+
64+DOM 트리를 살펴보는 간단한 노트: 노드를 순차적으로 접근하려고 한다면, **FirstChild** 와 **NextSibling** 프로퍼티( 전방으로 재귀호출 하기 위해)를 사용하거나 **LastChild** 와 **PreviousSibling** (후방으로 재귀호출) 것이 최상의 방법이다. 랜덤 접근을 위해서는 **ChildNodes** 또는 **GetElementsByTagName** 메쏘드를 사용할 수 있으나, 이것들은 TDOMNodeList 객체를 생상하므로 반드시 해제 해 주어야 한다. 이것은 MSXML 같은 다른 DOM 구현과는 다르다. 이는 FCL 구현이 객체를 기반으로 한 것이지 인터페이스를 기반으로 한 것이 아니기 때문이다.
65+
66+다음 예제는 폼에 잇는 TMemo에 노드의 이름을 프린트 하는 방법을 보여준다.
67+
68+아래는 'C:\Programas\teste.xml'로 불리는 XML 파일이다:
69+
70+``` xml
71+ <?xml version="1.0"?>
72+ <images directory="mydir">
73+ <imageNode URL="graphic.jpg" title="">
74+ <Peca DestinoX="0" DestinoY="0">Pecacastelo.jpg1.swf</Peca>
75+ <Peca DestinoX="0" DestinoY="86">Pecacastelo.jpg2.swf</Peca>
76+ </imageNode>
77+ </images>
78+```
79+
80+다음은 태스크를 실행하기 위한 파스칼 코드이다:
81+
82+``` pascal
83+ var
84+ Documento: TXMLDocument;
85+ Child: TDOMNode;
86+ j: Integer;
87+ begin
88+ ReadXMLFile(Documento, 'C:\Programas\teste.xml');
89+ Memo.Lines.Clear;
90+ // FirstChild 와 NextSibling 프로퍼티를 사용하여
91+ Child := Documento.DocumentElement.FirstChild;
92+ while Assigned(Child) do
93+ begin
94+ Memo.Lines.Add(Child.NodeName + ' ' + Child.Attributes.Item[0].NodeValue);
95+ // ChildNodes 메쏘드 사용
96+ with Child.ChildNodes do
97+ try
98+ for j := 0 to (Count - 1) do
99+ Memo.Lines.Add(Item[j].NodeName + ' ' + Item[j].FirstChild.NodeValue);
100+ finally
101+ Free;
102+ end;
103+ Child := Child.NextSibling;
104+ end;
105+ Documento.Free;
106+ end;
107+```
108+
109+이것은 다음과같이 프린트할 것이다:
110+
111+ imageNode graphic.jpg
112+ Peca Pecacastelo.jpg1.swf
113+ Peca Pecacastelo.jpg1.swf
114+
115+### TreeView 를 XML과 함께 넣기
116+
117+XML 파일을 사용하는 일반적인 것은 파싱하고트리와 같은 형식으로 내용을 보여주고자 함일 것이다. 라자루스의 "Common Controls" 탭에서 TTreeView 컴포넌트를 찾을 수 있을 것이다.
118+
119+아래에 있는 이 함수는 이미 파일에서 로드되거나 코드에서 생성된 XML 도큐먼드를 가져 올 것이며, 그 내용을 TreeView에 넣어 줄 것이다. 각 노드의 캡션은 각 노드의 첫번째 속성 값이 될 것이다.
120+
121+``` pascal
122+procedure TForm1.XML2Tree(tree: TTreeView; XMLDoc: TXMLDocument);
123+var
124+ iNode: TDOMNode;
125+
126+ procedure ProcessNode(Node: TDOMNode; TreeNode: TTreeNode);
127+ var
128+ cNode: TDOMNode;
129+ begin
130+ if Node = nil then Exit; // leaf에 도달하면 정지
131+
132+ // 노드를 트리에 추가
133+ TreeNode := tree.Items.AddChild(TreeNode, Node.Attributes[0].NodeValue);
134+
135+ // 차일드 노드로 감
136+ cNode := Node.FirstChild;
137+
138+ // 모든 차일드 노드를 처리
139+ while cNode <> nil do
140+ begin
141+ ProcessNode(cNode, TreeNode);
142+ cNode := cNode.NextSibling;
143+ end;
144+ end;
145+
146+begin
147+ iNode := XMLDoc.DocumentElement.FirstChild;
148+ while iNode <> nil do
149+ begin
150+ ProcessNode(iNode, nil); // 회귀
151+ iNode := iNode.NextSibling;
152+ end;
153+end;
154+```
155+
156+### XML 도큐먼트 수정 하기
157+
158+먼저, 기억할 것은 TDOMDocument 는 DOM에 대한 핸들이라는 것이다. XML 도큐먼트를 로딩하거나 TDOMDocument 를 한개 생성하여 이 클래스의 인스턴스를 얻을 수 있다.
159+
160+다른 한편으로 노드는 통상적인 객체처럼 생성될 수 없다. 생성하기 위해서는 *반드시* TDOMDocument에서 제공하는 메쏘드를 사용하여야 한다. 통상적인 객체는 트리상의 정확한 위치에 넣기 위해서 다른 메써드를 사용한다. 이는 노드는 DOM사의 특정한 도큐먼트에 의해 *소유되어야*하기 때문이다.
161+
162+아래는 TDOMDocument에 있는 몇몇 공통 메써드이다:
163+
164+``` pascal
165+ function CreateElement(const tagName: DOMString): TDOMElement; virtual;
166+ function CreateTextNode(const data: DOMString): TDOMText;
167+ function CreateCDATASection(const data: DOMString): TDOMCDATASection;
168+ virtual;
169+ function CreateAttribute(const name: DOMString): TDOMAttr; virtual;
170+```
171+
172+다음은 선택된 아이템을 TTreeView상에 위치시키고 자식 노드를 그것이 표현하는 XML 도큐먼트에 삽입하는 예제 메쏘드를 보여 줄 것이다. TreeView는 [[Networking|XML2Tree 함수를]] 사용하여 XML 파일의 내용으로 먼저 채워져 있어야 한다.
173+
174+``` pascal
175+procedure TForm1.actAddChildNode(Sender: TObject);
176+var
177+ position: Integer;
178+ NovoNo: TDomNode;
179+begin
180+ {*******************************************************************
181+ * 선택된 원소를 찾고
182+ *******************************************************************}
183+ if TreeView1.Selected = nil then Exit;
184+
185+ if TreeView1.Selected.Level = 0 then
186+ begin
187+ position := TreeView1.Selected.Index;
188+
189+ NovoNo := XMLDoc.CreateElement('아이템');
190+ TDOMElement(NovoNo).SetAttribute('이름', '아이템');
191+ TDOMElement(NovoNo).SetAttribute('Heennavi', '흰나비');
192+ with XMLDoc.DocumentElement.ChildNodes do
193+ begin
194+ Item[position].AppendChild(NovoNo);
195+ Free;
196+ end;
197+
198+ {*******************************************************************
199+ * TreeView를 업데이트하고
200+ *******************************************************************}
201+ TreeView1.Items.Clear;
202+ XML2Tree(TreeView1, XMLDoc);
203+ end
204+ else if TreeView1.Selected.Level >= 1 then
205+ begin
206+ {*******************************************************************
207+ * 이 함수는 트리의 첫번째 수준에서만 동작하지만,
208+ * 어떤 수의 수준에서라도 동작할 수 있도록 쉽게 수정할 수 있다.
209+ *******************************************************************}
210+ end;
211+end;
212+```
213+
214+### 문자열로 부터 TXMLDocument 생성
215+
216+MyXmlString에 있는 모든 XML 파일에서 다음 코드는 그것의 DOM을 생성할 것이다.
217+
218+``` pascal
219+Var
220+ S : TStringStream;
221+ XML : TXMLDocument;
222+
223+begin
224+ S:= TStringStream.Create(MyXMLString);
225+ Try
226+ S.Position:=0;
227+ XML:=Nil;
228+ ReadXMLFile(XML,S); // 완전한 XML 도큐먼트
229+ //다른 방법으로는:
230+ ReadXMLFragment(AParentNode,S); // XML 조각들만 읽는다.
231+ Finally
232+ S.Free;
233+ end;
234+end;
235+```
236+
237+### 문서 검증
238+
239+2007년 3월 이래, DTD 인증 도구가 FCL XML 파서에 추가 되었다. 인증은 미리 정의된 규칙에 문서가 적합한지 문서의 논리적인 구조를 체크하는 것으로, *Document Type Definition* (DTD).이라고 부른다.
240+
241+DTD를 이용한 XML 문서의 예가 있다:
242+
243+``` xml
244+ <?xml version='1.0'?>
245+ <!DOCTYPE root [
246+ <!ELEMENT root (child)+ >
247+ <!ELEMENT child (#PCDATA)>
248+ ]>
249+ <root>
250+ <child>This is a first child.</child>
251+ <child>And this is the second one.</child>
252+ </root>
253+```
254+
255+'root' 원소를 지정하는 이 DTD는 반드시 한개 또는 그 이상의 'child' 원소를 가져야 하며, 그 'child' 원소는 내부에 한개의 문자 데이터만 가질 수 있다. 만약 파서가 이 규칙에 위배되는 것을 탐지한면 이것을 보고할 것이다.
256+
257+그런 문서를 로딩하는 것은 약간 복잡하다. TStream 객체에 있는 XML 데이터를 가지고 있다고 가정하자:
258+
259+``` pascal
260+procedure TMyObject.DOMFromStream(AStream: TStream);
261+var
262+ Parser: TDOMParser;
263+ Src: TXMLInputSource;
264+ TheDoc: TXMLDocument;
265+begin
266+ // 파서 객체 생성
267+ Parser := TDOMParser.Create;
268+ // 그리고 입력 소스 생성
269+ Src := TXMLInputSource.Create(AStream);
270+ // 인증을 원하고
271+ Parser.Options.Validate := True;
272+ // 통지를 받을 수있는 에러 핸들러를 할당
273+ Parser.OnError := @ErrorHandler;
274+ // 이제 작업을 수행
275+ Parser.Parse(Src, TheDoc);
276+ // ...그리고 깨끗이 정리
277+ Src.Free;
278+ Parser.Free;
279+end;
280+
281+procedure TMyObject.ErrorHandler(E: EXMLReadError);
282+begin
283+ if E.Severity = esError then // 우리는 오직 인증 에러에 만 관심있다.
284+ writeln(E.Message);
285+end;
286+```
287+
288+### 공백문자
289+
290+만약 노드 텍스트에서 선행 공작 문자열을 보존하려면 XML 문서를 로드하는 위의 방법을 사용하면 된다. 선행 공백 문자열은 기본적으로 무시하도록 되어있다. 이것은 ReadXML(...)함수가 텍스트 노드에 있는 어떠한 선행 공백문자로 리턴하지 않기 때문이다. *Parser.Parse(Src, TheDoc)* 를 호출하기 전에 다음 라인을 삽입한다
291+
292+``` pascal
293+Parser.Options.PreserveWhitespace := True;
294+```
295+
296+이렇게 하면 파서가 모든 공백 문자를 리턴하도록 한다. 이것은 XML 문서에 있는 모든 개행 문자를 포함하여 더 읽기 쉽도록 해준다.
297+
298+### XML 파일 생성
299+
300+XML 파일을 쓰는 완전한 코드가 아래에 있다. (DeveLazarus 블로그에 있는 튜토리얼에서 가져왔다) uses 절에 DOM 과 XMLWrite 라이브러리가 있다는 것을 기억하시오
301+
302+``` pascal
303+unit Unit1;
304+
305+{$mode objfpc}{$H+}
306+
307+interface
308+
309+uses
310+ Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls,
311+ DOM, XMLWrite;
312+
313+type
314+ { TForm1 }
315+ TForm1 = class(TForm)
316+ Button1: TButton;
317+ Label1: TLabel;
318+ Label2: TLabel;
319+ procedure Button1Click(Sender: TObject);
320+ private
321+ { private declarations }
322+ public
323+ { public declarations }
324+ end;
325+
326+var
327+ Form1: TForm1;
328+
329+implementation
330+
331+{ TForm1 }
332+
333+procedure TForm1.Button1Click(Sender: TObject);
334+var
335+ xdoc: TXMLDocument; // 문서에 대한 변수
336+ RootNode, parentNode, nofilho: TDOMNode; // 노드에 대한 변수
337+begin
338+ // 문서 생성
339+ xdoc := TXMLDocument.create;
340+
341+ // root 노드 생성
342+ RootNode := xdoc.CreateElement('register');
343+ Xdoc.Appendchild(RootNode); // root 노드 저장
344+
345+ // 부모 노드 생성
346+ RootNode:= xdoc.DocumentElement;
347+ parentNode := xdoc.CreateElement('usuario');
348+ TDOMElement(parentNode).SetAttribute('id', '001'); // 부모 노드에 대한 속성 생성
349+ RootNode.Appendchild(parentNode); // 부모 노드 저장
350+
351+ // 자식 노드 생성
352+ parentNode := xdoc.CreateElement('nome'); // 자식 노드 생성
353+ //TDOMElement(parentNode).SetAttribute('sexo', 'M');// 속성 생성
354+ nofilho := xdoc.CreateTextNode('Fernando'); // 값을 노드에 삽입
355+ parentNode.Appendchild(nofilho); // 노드 저장
356+ RootNode.ChildNodes.Item[0].AppendChild(parentNode);// 자식 노드를 해당하는 부모 노드에 삽입
357+
358+ // 자식 노드 생성
359+ parentNode := xdoc.CreateElement('idade'); // create a child node
360+ //TDOMElement(parentNode).SetAttribute('ano', '1976'); // create atributes
361+ nofilho := xdoc.CreateTextNode('32'); // insert a value to node
362+ parentNode.Appendchild(nofilho); // save node
363+ .ChildNodes.Item[0].AppendChild(parentNode); // insert a childnode in respective parent node
364+
365+ writeXMLFile(xDoc,'teste.xml'); // write to XML
366+ Xdoc.free; // free memory
367+end;
368+
369+initialization
370+ {$I unit1.lrs}
371+
372+end.
373+```
374+
375+결과는 아래의 XML 파일이 될 것이다:
376+
377+``` xml
378+<?xml version="1.0"?>
379+<register>
380+ <usuario id="001">
381+ <nome>Fernando</nome>
382+ <idade>32</idade>
383+ </usuario>
384+</register>
385+```
386+
387+--Fernandosinesio 22:28, 24 April 2008 (CEST)fernandosinesio@gmail.com
388+
389+### 인코딩
390+
391+SVN 개정판 12582에서 시작하여 XML 리더는 외부 디코더를 사용한 어떠한 인코딩된 데이터라도 처리할 수 있다.
392+
393+XML 표준에 의하면, XML의 첫번째 라인에 있는 인코딩 속성은 실제 코딩이 UTF-8 이나 UTF-16(BOM이 있으면 감지할 수 있다)인 경우에는 선택 사항이다. 0.9.26 버전 라자루스에서는, TXMLDocument에 인코딩 속성이 있지만, 무시된다. writeXMLFile 은 항상 UTF-8을 이용하며 XML 파일의 첫 라인에 인코딩 속성을 생성하지 않는다.
394+
395+## 더 볼 것
396+
397+- [[XML Decoders|XML 디코더]]
398+- [[Using INI Files|INI 파일의 사용]]
399+- [[fcl-xml]]
400+- [[Internet Tools|인터넷 도구]]
401+
402+## 외부 링크
403+
404+- [W3Schools](http://www.w3schools.com/xml/default.asp) Xml 튜토리얼
405+
406+- [Thomas Zastrow 문서](http://www.thomas-zastrow.de/texte/fpcxml/index.php) FPC 와 XML
407+
408+------------------------------------------------------------------------
409+
410+[[Multithreaded Application Tutorial|멀티 쓰레드 응용프로그램 튜토리얼]]
411+
412+---
413+*From the Free Pascal wiki, page "XML Tutorial/ko", as it stood on 2020-03-02 after a change by Trev, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history