델파이에서 XML에 CRLF를 쓰고 읽으려고 하면
CRLF를 써도 읽어지는 것은 LF만 읽어진다.

인터넷에서 열심히 뒤져 봐도 뾰족한 대안을 못찾았다.

그래서 생각해낸 방법은 LF만 있을 경우 LF를 모두 CRLF로 바꾸면 된다.

먼저 LF만 있는지 확인하는 방법


function CheckOnlyLF(sSrc: string): boolean;
var
  iCrLf, iLf : integer;
begin
  result := false;

  iCrLf := Pos(#13 + #10, sSrc);
  iLf := Pos(#10, sSrc);

  if (iCrLf = 0) and (iLf > 0) then result := true;
end;

이 소스는 LF를 하나만 검색하면 그냥 나와버린다.

그리고 LF를 모두 CRLF로 변경하려면 간단하게 할 수 있다.

function LfToCrLf(sSrc: string): string;
begin
  if CheckOnlyLF(sSrc) = true then
    result := StringReplace(sSrc, #10, #13+#10, [rfReplaceAll, rfIgnoreCase]);
end;

이 함수에도 좀 문제가 있을 수 있다.
문자열에 LF와 CRLF가 섞여있으면
CRCRLF가 되어 버린다. -.-;;
하기야 이렇게 표시에는 문제가 없지만 문자가 하나 더 추가되는 것이 찜찜하면
모든 문자열을 일일히 검색하면서 CRLF인지 LF인지를 검색하는 수 밖에 없다.

이렇게 까지하는 것은 귀찮아서 생략
혹시 그렇게 프로그램을 짜신 분은 트랙백해주세요. ^^;


Posted by 떡잎

설명이 따로 필요 없는 예제

<html>
<body>

<script type="text/javascript">
var xmlDoc=null;
if (window.ActiveXObject)
{
  // IE용
  xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
}
else if (document.implementation.createDocument)
{
  // Mozilla, Firefox, Opera, 기타 용
  xmlDoc=document.implementation.createDocument("","",null);
}
else
{
  alert('XML을 사용못하는 브라우저임');
}

if (xmlDoc!=null)
{
  xmlDoc.async=false;
  xmlDoc.load("tel.xml");

  var x=xmlDoc.getElementsByTagName("mem");
  for (i=0;i<x.length;i++)
  {
    document.write(x[i].getElementsByTagName("name")[0].childNodes[0].nodeValue);
    document.write(':');
    document.write(x[i].getElementsByTagName("cell")[0].childNodes[0].nodeValue);
    document.write('<br>');
  }
}
</script>
</body>
</html>

tel.xml 파일

<?xml version="1.0" encoding="euc-kr"?>
<!-- Edited by Notepad-->
<MyCompany>
 <mem>
  <part>영업</part>
  <name>홍길동</name>
  <tno>1111</tno>
  <cell>01033334444</cell>
  <birth>11/15</birth>
 </mem>
 <mem>
  <part>관리</part>
  <name>홍당무</name>
  <tno>2222</tno>
  <cell>01022220000</cell>
  <birth>11/11</birth>
 </mem>
 <mem>
  <part>개발</part>
  <name>최말봉</name>
  <tno>6153</tno>
  <cell>01077775555</cell>
  <birth>3333</birth>
 </mem>
 <mem>
  <part>홍보</part>
  <name>최고봉</name>
  <tno>4444</tno>
  <cell>01088889999</cell>
  <birth>01/15</birth>
 </mem>
</MyCompany>

자바 스크립트에서 XML 파일의 맴버들을 참조하는 것은 의외로 쉬웠다.



 

Posted by 띠리

델파이 XML Data Binding으로 xml 파일 조작하기

소스를 열어둔 상태에서 Tool Palette를 보면 Delphi Projects | XML이 있다.
그 밑에 XML Data Binding이 있다.
그것을 클릭한다.

사용자 삽입 이미지

그러면 아래 윈도우가 표시되어지고
조작할  XML 파일을 선택하고 "Next" 버튼을 누른다.

사용자 삽입 이미지

XML Data Binding Wizard 화면에서도 특별히 고치지 않고 "Next" 버튼을 누른다.

사용자 삽입 이미지

그러면 아래와 같이 새로운 pas파일이 생성되면서 조금전에 선택한 XML 파일의 조작하기 쉽게 xml 파일이 바인딩된다.

사용자 삽입 이미지

그리고 이 바인딩된 xml 파일을 사용하고자 하는 곳에
추가된 unit명과 xmldom, XMLIntf, XMLDoc을 uses에 추가해야 된다.

xml Data Binding을 쓰면 간단하게 xml 파일에 노드를 추가하고
삭제하고 검색하고 변경하는 것이 가능하지만 좀 자유도(?)가 많이 떨어지게 된다.

자세한 내용은 첨부한 소스를 참조하는 것이 좋을 것같다.

unit uMain;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, stdctrls, extctrls
  ,CarList, xmldom, XMLIntf, XMLDoc;

type
  TForm1 = class(TForm)
    ListBox1: TListBox;
    ListBox2: TListBox;
    Button1: TButton;
    procedure ListBox1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }

    ixList : IXMLItemListType;
    ixDetail :Array of IXMLItemType;

  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  iListCount : integer;
  i : integer;
  sTest : string;
begin

  iListCount := ixList.Count;
  setLength(ixDetail, iListCount);

  ListBox1.Clear;

  // xml 파일에서 아이템 가져오기
  for i := 0 to iListCount - 1 do
  begin
    ixDetail[i] := ixList.Get_Item(i);
    ListBox1.Items.Add(ixDetail[i].Name)
  end;

end;

procedure TForm1.FormCreate(Sender: TObject);
var
  CurrentPath : array [0..256] of char;
begin

  // 어플리케이션이 위치하는 디렉토리 얻기
  GetCurrentDirectory(sizeof(CurrentPath),CurrentPath);

  // xml을 읽어서 아이템 리스트 로드
  ixList := LoadItemList(CurrentPath + '\CarList.xml');
  Application.GetNamePath

end;

procedure TForm1.ListBox1Click(Sender: TObject);
var
  i: integer;
begin
  i := ListBox1.ItemIndex;

  ListBox2.Clear;
  // 선택한 아이템의 상세 정보 표시
  //ListBox2.Items.Add(ixDetail[i].Sec);
  ListBox2.Items.Add('Color = ' + ixDetail[i].Color);
  ListBox2.Items.Add('Maker = ' + ixDetail[i].Maker);
end;

end.



프로젝트 소스와 xml 파일

Posted by 띠리

델파이에서 XMLDocument 컴포넌트를 사용해서
XML 파일 불러 TreeView에 표시하는 소스

XML 파일 불러오기

// XML 파일 읽어오기
procedure TForm1.Button2Click(Sender: TObject);
Var
  xdSoft : TXMLDocument;
begin

  OpenDialog1.Filter := 'Xml file|*.xml';

  if OpenDialog1.Execute then
  begin

    // XML Document 만들기
    xdSoft := TXMLDocument.Create(Application);

    // XML Document 불러오기
    xdSoft.LoadFromFile(OpenDialog1.FileName);
    xdSoft.Active := True;

    // TreeView 기존 데이터 삭제
    TreeView1.Items.Clear;

    // XML 구조를 읽어서 TreeView에 표시
    MakeTree(nil, xdSoft.DocumentElement);

    // TreeView 다 펴서 보여주기
    TreeView1.FullExpand;

    xdSoft.Free;

  end;

end;


XML 파일을 트리뷰에 표시

// XML 구조를 읽어서 TreeView에 표시
procedure TForm1.MakeTree(TreeNode : TTreeNode; XMLNode : IXMLNode);
var
  Node: TTreeNode;
  i: integer;
  sNode : string;
begin

  sNode := '';

  // 노드 밑에 노드가 없을 때
  if (XMLNode.NodeType = ntText) then
  begin

    // 노드에 Attribute가 있을 때
    if XMLNode.AttributeNodes.Count > 0  then
    begin
      sNode := ' |';
      For i :=0 To XMLNode.AttributeNodes.Count - 1 Do
      begin
        sNode := sNode +
        XMLNode.AttributeNodes.Get(i).NodeName + ' : ' +
        XMLNode.AttributeNodes.Get(i).NodeValue + '|';
      end;
    end;

    // 트리뷰에 노드 추가
    Node := TreeView1.Items.AddChild(TreeNode, XMLNode.NodeValue + sNode);

  end

  // 노드 밑에 노드가 있을 때
  else
  begin

    // 노드에 Attribute가 있을 때
    if XMLNode.AttributeNodes.Count > 0  then
    begin
      sNode := ' |';
      For i :=0 To XMLNode.AttributeNodes.Count - 1 Do
      begin
        sNode := sNode +
        XMLNode.AttributeNodes.Get(i).NodeName + ' : ' +
        XMLNode.AttributeNodes.Get(i).NodeValue + '|';
      end;
    end;

    // 트리뷰에 노드 추가
    Node := TreeView1.Items.AddChild(TreeNode, XMLNode.NodeName + sNode);

  end;

  // 노드 밑에 노드가 있을 경우
  for i :=  0 to  XMLNode.ChildNodes.Count - 1 do
    // XML 구조를 읽어서 TreeView에 표시
    MakeTree(Node, XMLNode.ChildNodes.Nodes[i]);

end;

XML 파일의 모든 노드와 속성을 표시하는 소스

 

invalid-file

델파이 2006 소스

델파이 2006 소스
Posted by 띠리

델파이에서 XMLDocument 컴포넌트로 XML파일을 읽고 쓰는 방법은
말로 설명하기는 좀 어렵고 그냥 소스를 보는 것이 알기 쉬울 것같다.

먼저 uses에  XMLDoc, XMLIntf을 추가한다.

XML 파일 쓰기

// XML 파일 만들고 쓰기
procedure TForm1.Button1Click(Sender: TObject);
Var
  xdSoft : TXMLDocument;
  xnRoot  : IXMLNode;
  xnChild : IXMLNode;
  xnGrandchild : IXMLNode;
begin

  // XML Document 만들기
  xdSoft := TXMLDocument.Create(Application);
  xdSoft.Active := True;
  xdSoft.Encoding:= 'euc-kr';

  // 루트 노드 만들기
  xnRoot := xdSoft.AddChild('SoftList');
  // 노드에 속성 설정
  xnRoot.Attributes['LatestUpdate'] := FormatDateTime('YYYY/MM/DD', Now);


  // 테스트 데이터 추가

###################################################################### //

  // 노드 밑에 노드 만들기
  xnChild := xnRoot.AddChild('Soft');
  xnChild.Attributes['Soft_name'] := 'PhotoSharp';

  xnGrandchild := xnChild.AddChild('Detail');
  xnGrandchild.Attributes['maker'] := 'Adove';
  xnGrandchild.Attributes['section']  := 'Drawing tool';
  xnGrandchild.Attributes['Price']  := 5000;

  xnGrandchild := xnChild.AddChild('Extra');
  xnGrandchild.Attributes['name'] := 'toy';
  xnGrandchild.Attributes['note']  := 'for child';

  xnGrandchild := xnChild.AddChild('Stock');
  // 노드 값 설정
  xnGrandchild.NodeValue := 100;

  // ---------------------------------------------------------------------- //

  xnChild := xnRoot.AddChild('Soft');
  xnChild.Attributes['Soft_name'] := 'OverOffice';

  xnGrandchild := xnChild.AddChild('Detail');
  xnGrandchild.Attributes['maker'] := 'OverSoft';
  xnGrandchild.Attributes['section']  := 'office tool';
  xnGrandchild.Attributes['Price']  := 2000;

  xnGrandchild := xnChild.AddChild('Extra');
  xnGrandchild.Attributes['name'] := 'notebook';
  xnGrandchild.Attributes['note']  := 'no comment';

  xnGrandchild := xnChild.AddChild('Stock');
  xnGrandchild.NodeValue := 50;

  // ###################################################################### //

  // XML Document 저장하기
  xdSoft.SaveToFile('C:\Test.Xml');
  xdSoft.Free;

end;

만들어진 XML 파일

<?xml version="1.0" encoding="euc-kr" ?>
<SoftList LatestUpdate="2007-10-12">
  <Soft Soft_name="PhotoSharp">
    <Detail maker="Adove" section="Drawing tool" Price="5000" />
    <Extra name="toy" note="for child" />
    <Stock>100</Stock>
  </Soft>
  <Soft Soft_name="OverOffice">
    <Detail maker="OverSoft" section="office tool" Price="2000" />
    <Extra name="notebook" note="no comment" />
    <Stock>50</Stock>
  </Soft>
</SoftList>

XML 파일 읽기

// XML 파일 읽어오기
procedure TForm1.Button2Click(Sender: TObject);
Var
  xdSoft : TXMLDocument;
  xnChild : IXMLNode;
  xnGrandchild : IXMLNode;
  i : Integer;
  j : Integer;
  k : Integer;
  sMsg : string;
  sTest : string;
begin

  // XML Document 만들기
  xdSoft := TXMLDocument.Create(Application);

  // XML Document 불러오기
  xdSoft.LoadFromFile('C:\Test.Xml');
  xdSoft.Active := True;

  // 루트 노드가 없을 경우 종료
  if xdSoft.ChildNodes.First = nil then Begin
    Exit;
  End;

  // 루트에 딸려있는 노드 분
  For i := 0 To xdSoft.DocumentElement.ChildNodes.count - 1 Do
  Begin
    sMsg := '';
    sTest := '';

    xnChild := xdSoft.DocumentElement.ChildNodes[i];
    xnGrandchild := xnChild.ChildNodes[0];

    // Soft 노드의 첫번째 노드의 속한 attribute 분
    For j :=0 To xnGrandchild.AttributeNodes.Count - 1 Do
    begin

    sMsg := sMsg +
      '    ' + xnGrandchild.AttributeNodes.Get(j).NodeName + ' : ' +
      xnGrandchild.AttributeNodes.Get(j).NodeValue + #13

    end;
    sTest := sTest + xnChild.NodeName + ' : ';
    sTest := sTest + xnChild.AttributeNodes.Get(0).NodeValue + #13;

    xnGrandchild := xnChild.ChildNodes[2];

    ShowMessage(
      sTest + #13 +
      sMsg + '    ----------' + #13 +
      '    ' + xnGrandchild.NodeName + ' : ' +
      xnGrandchild.NodeValue
    );

  End;

  xdSoft.Free;

end;

개인적으로 생각하기에는 XML Data Binding보다 XML Documnet 컴포넌트를
쓰는것이 더 깔끔하게 프로그램을 만들 수 있을 것같다.






 

Posted by 띠리

http://dn.codegear.com/kr/article/34110  원 링크

Delphi XML Binding Wizard Tutorial

작성자: Andrea Raimondi

요약: The Delphi XML Binding Wizard requires some understanding to be used. I'll show you

    Introduction

The XML binding wizard lets developers using XML files avoid all the mess related to xml node management. This is obtained by abstracting the xml document to a set of interfaces defining the final values, rather than nodes.

    How the file is handled at the binding level

Each xml file is composed of a root node and several child nodes.

This means that the root node code will be an interface inheriting from XMLDocument.

While this may seem obvious to experienced users, beginners have to consider what this means, because it implies several other things.

First of all, it means that you can access the underlying original XML document if you have to perform some operations, such as an XPath selection.

Second, it implies that - if you really want to - you can reuse code relying on the IXMLDocument interface for your current binding. This is useful if you have, for example, routines to bind an XML document to a treeview (which is quite common).

Third, it means that it's very easy to generate a brand new XML file using the binding and then expose the generated XML, just use the XML property of type TStrings.

Child nodes are another consideration. The wizard can distinguish between composite and simple nodes. Thus, if you have a "items" node with several "item" nested nodes, the wizard will be smart enough to recognize the pattern and accomodate your generated code accordingly.

Child nodes can derive from any IXMLNode or inherited interface according to the type of node, except IXMLDocument(which is reserved, as mentioned above, to the root node).

You will notice that there's no function whatsoever to create a child node unless it is a composite node.

This is what the wizard is all about: you set interface properties and Delphi will take care of creating the nodes.

If, however, there's a composite node, there's then going to be an ADD method allowing you to set the child nodes. This method is a function returning the most convenient interface, like in this example:

var MyChildNode : IMyChildNode;
begin
  MyChildNode := MyParentNode.Add;
  // Set MyChildNode properties here, Delphi behind the scenes will create the nodes.
end;

    When to use the wizard

The wizard can be used in most occasions. It's very handy especially for those XML files that can get slightly convoluted or that are not under our control. The best feature of the wizard is that, if a new, compatible XML schema or file is sent to you, you can simply re-generate the source and you're done.

    Alternatives to the wizard

The main, supported, alternative to the wizard is the use of a client dataset.

While it's not exactly an XML file in its own merit (i.e. the CDS really is a database), it can be saved to XML and can also be transformed (using the XML mapper) into a custom XML file.

Thus, you can prototype your data model using a client dataset, transform it to an XML file, feed it to the wizard, and voilà.

    What to feed to the wizard

The binding wizard can be fed with several different xml file types:

  • Data files (with .xml extension)
  • Schema files (with .xsd extension)
  • XTR files (very rare, just don't care)

You'll likely feed the wizard with XML files, less likely (but still very possible) with schema ones.

    A sample file import

Let's see a sample XML file.

<?xml version="1.0" encoding="UTF-16"?>
<rootelement>
  <childnodes attr1="1">
      <childnode attr2="2">
         </childnode>
         <childnode attr2="2">
         </childnode>
         <childnode attr3="3">
         </childnode>
    </childnodes>
    <anotherchildnode>
      with text in it
    </anotherchildnode>
</rootelement>

Start the wizard and import it.

You will obtain these interfaces:

{ IXMLRootelementType }
IXMLRootelementType = interface(IXMLNode)
    ['{875F00D6-2822-4DC7-B4F7-6178F9456EC8}']
    { Property Accessors }
    function Get_Childnodes: IXMLChildnodesType;
    function Get_Anotherchildnode: WideString;
    procedure Set_Anotherchildnode(Value: WideString);
    { Methods & Properties }
    property Childnodes: IXMLChildnodesType read Get_Childnodes;
    property Anotherchildnode: WideString read Get_Anotherchildnode
      write Set_Anotherchildnode;
  end;

{ IXMLChildnodesType }

  IXMLChildnodesType = interface(IXMLNodeCollection)
    ['{F26112C9-A8F2-4852-8EE2-86E50702015B}']
    { Property Accessors }
    function Get_Attr1: Integer;
    function Get_Childnode(Index: Integer): IXMLChildnodeType;
    procedure Set_Attr1(Value: Integer);
    { Methods & Properties }
    function Add: IXMLChildnodeType;
    function Insert(const Index: Integer): IXMLChildnodeType;
    property Attr1: Integer read Get_Attr1 write Set_Attr1;
    property Childnode[Index: Integer]: IXMLChildnodeType 
      read Get_Childnode; default;
  end;

{ IXMLChildnodeType }

  IXMLChildnodeType = interface(IXMLNode)
    ['{E8DDAFCC-84BC-4067-808F-0D5DAF829436}']
    { Property Accessors }
    function Get_Attr2: Integer;
    function Get_Attr3: Integer;
    procedure Set_Attr2(Value: Integer);
    procedure Set_Attr3(Value: Integer);
    { Methods & Properties }
    property Attr2: Integer read Get_Attr2 write Set_Attr2;
    property Attr3: Integer read Get_Attr3 write Set_Attr3;
  end;

Now, if we look at this source code, we’ll see that, for instance, “AnotherChildNode” is a simple string, whereas ChildNodes has the famous .ADD method.



How do you use those interfaces? It’s pretty simple:

procedure NewXMLFile( out RootNode : IXMLRootelementType;AnotherChildElement : String );
begin
  RootNode := NewRootelement;
  RootNode.AnotherChildElement := AnotherChildElement;
end;

procedure AddChildElement( RootNode: IXMLRootElementType;Attr2, Attr3 : String );
var ChildNode : IXMLChildNodeType;
begin
   ChildNode := RootNode.ChildNodes.Add;
   ChildNode.Attr2 := Attr2;
   ChildNode.Attr3 := Attr3;
end;

Let’s now have a look at how the “NewRootElement” function is implemented:

function Newrootelement: IXMLRootelementType;
begin
  Result := NewXMLDocument.GetDocBinding('rootelement', TXMLRootelementType) as IXMLRootelementType;
end;

The “NewXMLDocument” function is declared in XMLDoc.pas and creates an interfaced TXMLDocument instance.

    When not to use the XML binding wizard?

As you probably noticed, the XML binding requires a DOM-oriented parser. That is, you need to be loading and keeping all of your document in memory.

Thus, you shouldn’t be using it when you don’t need all of your document in memory. An example of this may be, for instance, some kind of tag based generator. Consider this XML file:

<?xml version="1.0"?>
<build>
  <taskdefs>
    <taskdef name="DelphiCompiler" ExeFile="Dcc.exe"/>
  </taskdefs>
  <tasks>
     <task taskdef="DelphiCompiler" file="MyConsoleApp.dpr"/>
  </tasks>
</build>

In this case, you simply need to parse each tag, you don’t need a DOM, thus you don’t need a bound XML. Yeah, you can still choose to use one, but this is not required.

Another case is when you need XPath, then you got to use the native IXMLDocument interface. But that’s for another tutorial, really.

    Conclusions

As you can see, XML binding is quite easy to use and powerful. I’m sure you’ll like it quite a bit, actually, when you’re going to use it.

Now you know the basics to use it proficiently, just go and bind your files!


 

공개 일자: : 3/2/2007 12:31:01 PM

Posted by 띠리
BLOG main image
프로그래밍 공부하면서 써가는 개인 노트 (따라서 여기에 씌여있는 소스의 신빙성을 보장 못함 -.-;;) 이 블로그 보면서 틀린 점이 있으면 꼬옥 알려주세요. by 띠리

공지사항

카테고리

분류 전체보기 (323)
Win32 SDK 초보 (27)
통신관련 (11)
MFC TIP (20)
C/C++ TIP (10)
개발기타 (10)
링크 (2)
견물생심 (24)
이것저것 (8)
용어메모 (3)
데이터베이스 (32)
비주얼 베이직 (10)
하드웨어 (3)
C# (42)
Xcode (3)
델파이 (82)
홈페이지 (5)
MindStorm (0)
낙서 (5)
스크래치 (0)
기타 (6)
아두이노 (1)
라즈베리파이 (2)
안드로이드 (6)
파이썬 (0)
WEB (2)
Excel VBA (0)
Total : 1,005,829
Today : 16 Yesterday : 380