태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.
   情  
Front Page
Tag | Location | Media | Guestbook | Admin   
 
'Web Development/Others'에 해당하는 글(20)
2009.09.08   LINQ to SQL을 사용하는 Application의 성능향상을 위한 10가지 제안
2008.09.12   XML 네임스페이스
2008.09.12   DTD문서 작성법3 (Entity, 컨티셔널 섹션)
2008.09.12   DTD문서 작성법 2 (속성작성, 노테이션)
2008.09.10   DTD문서 작성법 1 (엘리먼트가 가지는 데이터 유형 정의)
2008.09.10   XML 기초 2
2008.08.30   XML 기초 1
2008.07.29   IIS버전
2008.07.27   PHP를 배우시려면 여기로 가세요. (1)
2008.07.26   PHP에서 Form값 전달받기 (1)


LINQ to SQL을 사용하는 Application의 성능향상을 위한 10가지 제안

LINQ to SQL을 이용하면 Data Access작업에서 (과거에 비해) 놀라울 정도의 생산성 향상을 가져옵니다. 하지만, 그만큼 성늠이 우수한가에 대한 의문을 가질 수 밖에 없는 것은 사실입니다. 하지만 몇 가지 Benchmark들을 확인하면, LINQ to SQL을 제대로 사용하면, ADO.NET SQL DataReader의 93%의 성능까지 낼 수 있다고 합니다.

따라서 여기에서는 LINQ to SQL을 이용하여 데이터를 조회하고 수정하는데 있어서 성능을 향상시킬 수 있는 10가지 중요한 Tunning Point를 정리해드립니다.

  1. DataContext의 ObjectTrackingEnabled 속성이 필요하지 않다면, Off로 설정하십시요.
    만약 당신이 데이터를 조회만 하고, 데이터를 수정하지 않는다면 DataTracking 기능은 필요치 않습니다. DataTracking는 Server Memory에 올려진 LINQ데이터의 변화를 추적하여 DataContext.SubmitChage()되는 순간 그 변화를 반영하는 기능을 합니다. 만약 데이터를 조회만 한다면 아래와 같이 사용하십시요.
    using (DataClassesDataContext db = new DataClassesDataContext())
    {
         db.ObjectTrackingEnabled = false;
    }
  2. 전체 DB 개체들을 하나의 DataContext에 포함하지 마십시요.
    DataContext는 하나의 작업 단위를 표현해야지, 전체 DB를 표현해서는 안됩니다. 만약 당신의 DB개체 중에서 다른 개체와 연결되지 않고 독립적으로 동작하거나, 전혀 사용되지 않는 개체가 있다면, 그 개체들은 다른 DataContext로 분리하십시요. 만약 하나의 DataContext에 포함되어 있다면, 이러한 개체들은 DataContext를 선언할 때 불필요하게 메모리를 차지하며, DataConText의 CUD엔진이 사용하는 관리, 추적, 식별 비용을 증가시킬 뿐입니다.
    대신, 각 작업단위로 DataContext를 분리하는 것을 고려하십시요. 물론, Connection Pooling의 장점을 잃지 않기위해, 생성자를 이용하여 같은 Connection을 사용하도록 설정할 수 있습니다.
  3. 어디서든지 필요하다면 CompiledQuery를 이용하십시요.
    LINQ to SQL을 이용하여 표현식을 만들고 실행하기 위해서는 몇가지 단계가 존재합니다. 몇 가지 나열한다면 다음과 같습니다.
    1. Expression Tree의 생성
    2. Expression Tree를 SQL로 변환
    3. 생성된 SQL Query 실행
    4. 데이터 조회
    5. 조회된 데이터를 객체로 변환
    만약 당신이 같은 LINQ to SQL Query를 반복해서 사용한다고 할 때, 위의 과정 역시 반복된다고 한다면 그것은 불필요한 자원 낭비가 아닐 수 없습니다. 이 것이 바로 작은 System.Data.Linq 네임스페이스가 많은 자원을 소모하는 주 이유가 될 것입니다(같은 작업을 불필요하게 반복하는 것). CompiledQuery는 표현식을 Compile한 다음 이 것을 어딘가에 저장해둡니다. 그리고 같은 작업이 호출 되면 저장된 것을 통해 불필요한 Compile작업이 반복되는 것을 피하게 해줍니다. 이 기능은 정적 CompiledQuery.Compile메서드에 의해 실현할 수 있습니다. 예제는 다음과 같습니다.
    /*
     아래 NameSpance 선언 필요
     using System.Collections.Generic;
     using System.Data.Linq;
    */
    Func<DataClassesDataContext, IEnumerable<People>> func =
    	CompiledQuery.Compile<DataClassesDataContext, IEnumerable<People>> ((DataClassesDataContext db) => db.Peoples.Where<People>(t => t.PeopleName == "손대관"));
    이제 "func"는 Compiled Query로서 첫 실행시 단 한번만 Compile되게 됩니다. 다음 코드는 Compiled Query를 생성해서 Static Utility Class에 저장하는 예제입니다.
    /*
     아래 NameSpance 선언 필요
     using System.Collections.Generic;
     using System.Data.Linq;
    */
    public static class QueriesUtility
    {
    	public static Func<DataClassesDataContext, IEnumerable<People>> GetActivePeoples 
     	{
    		get
    		{
    			Func<DataClassesDataContext,IEnumerable<People>> func = 
    				CompiledQuery.Compile<DataClassesDataContext, IEnumerable<People>> ((DataClassesDataContext db)
    					=> db.Peoples.Where<People>(t => t.ActiveCheck = false));
    			return func;
    		}
    	}
    }
    이제 우리는 언제든지 위의 Compiled Query를 호출해서 사용할 수 있습니다.
    using (DataClassesDataContext db = new DataClassesDataContext())
    {
    	IEnumerable<People> p = QueriesUtility.GetActivePeoples(db);
    	lblTest.Text = p.Count().ToString();
    }
    이렇게 저장하고 실행하는 것은 반복적인 호출 비용을 단 한 1번의 호출 비용으로 감소시켜줍니다. 위와 같은 Compiled Query를 많이 만들어 둔다고 성능이 저하되지 않는 가 걱정하실 필요도 없습니다. 모든 Compiled Query는 처음 실행 될 때 단 한번만 Compile됩니다.
  4. DataLoadOptions.AssociateWith를 사용하여 필요한 데이터만 조회하세요.
    우리는 Primary Key로 연결된 관련된 데이터들을 한번에 읽어들여야 할 때, Load 또는 LoadWith를 사용합니다. 하지만 대부분의 경우 추가적인 필터링을 하게 되는데요, 이 경우 DataLoadOption.AssociateWith라는 Geniric Method는 매우 유용합니다. 이 뿐만 아니라 데이터를 조회할 때 필요한 데이터만 조회하는 것은 성능향상을 위한 첫걸음 입니다.
  5. 필요하지 않다면 Optimistic Concurrency을 끄세요.
  6. DataContext에 의해서 생성되는 데이터 조회 Query를 지속적으로 확인하세요.
    데이터를 조회할 때, DataContext는 Query를 자동으로 생성하는데요, 실제로 사용되지 않는 불필요한 코드가 생성될 수 있습니다. 성능개선을 위해서는 생성되는 Query를 지속적으로 감시하고, 불필요한 코드가 생성되지 않도록 LINQ to SQL 표현식을 수정해야 할 것입니다. 우리는 DataContext의 Log 속성을 이용해서 생성된느 SQL문을 볼 수 있습니다.
    using (DataClassesDataContext db = new DataClassesDataContext())
    {
    	System.IO.StreamWriter httpResponseStreamWriter = 
    		new StreamWriter(HttpContext.Current.Response.OutputStream);
    	db.Log = httpResponseStreamWriter;
    }
    위 코드는 생성된느 SQL문을 화면에 출력하는 코드입니다. Response개체 대신에 대상을 파일로 지정하는 것도 좋은 방법입니다.

    다른 방법은 'LINQ to SQL Debug Visualizer'를 사용하는 방법입니다. Debug 모드에서 손쉽게 생성된 SQL을 확인하고 실행할 수 있습니다. 'LINQ to SQL Debug Visualizer'에 대한 정보와 설치는 여기를 참조하세요.

  7. Attach()가 불필요한 Entity를 Context에 Attach하지 않도록 하세요
    조회된 Entity는 보통 DataContext에 연결되어 있으며, 내부적인 데이터 변화가 하나하나 추적되는 상태입니다. 이 상태에서는 Entity의 Update, Delete가 매우 쉽습니다. 하지만 Entity를 Serialize한 경우 처럼 DataContext와 Entity의 연결이 끊어진 상태도 존재합니다. 이럴 때 Attach를 통해 DataContext와 Entity를 연결하게 되는데, Entity를 Update 또는 Delete 할 경우에 Attach를 하는 것은 크게 문제가 되지 않습니다. 하지만 Update나 Delete하지 않음에도 Attach를 하는 경우가 있습니다. 이런 실수가 가장 많이 발생하는 경우가 바로 AttachAll()메서드로 Entity Collection을 DataContext로 연결하는 경우입니다.
    Object Tracking는 DataContext에 연결된 모든 개체의 Update, Delete를 추정하고 반영해주는 매우 멋진 기능이긴 하지만, 그만큼 많은 자원을 소모합니다. 따라서 위와 같이 Update, Delete가 되지 않는 Entity를 Attach하여 불필요하게 Entity가 추적되도록 하는 일은 최대한 피해야합니다.
  8. 불필요하게 Object Tracking가 작동하지 않는지 확인하세요
    다음과 같은 두 코드가 있을 때, 어느 쪽이 성능이 더 빠른지 생각해보라.
    예1)
    using (DataClassesDataContext db = new DataClassesDataContext())
    {
    	IQueryable<People> peopleList = db.Peoples
    		.Select(t => t);
    }
    
  9. 예2)
    using (DataClassesDataContext db = new DataClassesDataContext())
    {
    	var peopleList = db.Peoples
    		.Select(t => new
    		{
    			activeCheck = t.ActiveCheck,
    			deleteCheck = t.DeleteCheck
    		});
    }
    두 번째 표현식은 필요한 데이터를 걸러서 조회하고 있으며, 데이터 타입도 기존의 개체를 사용하는 것이 아닌 Var 타입을 사용하고 있기에, 첫번째 표현식이 더 빠를 것이라 생각할 수 있습니다. 하지만 실제로는 두번째 표현식이 더 자원을 적게 소모합니다. 첫 번째 표현식은 아직까지 Update, Delete 기능이 모두 지원하는 상태로 조회가 되므로 자원을 많이 소모합니다. 즉 첫번째 표현식은 Object Tracking가 동작하는 상태이며, 따라서 내부적으로는 데이터의 변화가 모두 일일이 추적되고 있는 상태입니다. 하지만 두번째 표현식 처럼 필요한 데이터를 걸러서 조회를 하게 되면, 조회된 List는 ReadOnly로 변하게 되며, 자연스럽게 보다 빠르게 동작합니다.
  10. 필요한 행만 걸러서 조회하세요.
    ListView에 데이터를 바인딩하고 Paging기능을 사용한다고 할 때, 우리는 Take와 Skip를 통해 필요한 페이지의 행만 조회할 수 있습니다. Skip, Take를 사용하지 않고 조회된 LINQ to SQL 결과를 바로 바인딩할 수 있지만, 그럴 경우 DB의 모든 데이터를 불러오기 때문에 행의 수에 비래하여 ListView의 속도도 느려집니다.
    아래는 해당페이지에 필요한 데이터만 조회하는 구문입니다.
    int intPageSize = 10;
    int intPageNum = 2;
    using (DataClassesDataContext context = new DataClassesDataContext())
    {
    	listView.DataSource = context.Peoples.Skip(intPageNum * intPageSize).Take(intPageSize);
    	listView.DataBind();
    }
    
  11. CompiledQuery를 오용하지 마세요.
    '어떻게 COmpiledQuery를 오용할 수 있는거지?'라는 생각을 하고 계신건 아닌지 모르겠네요. 여기서 하고자하는 말은 불필요한 최적화는 없어야 한다는 것입니다. CompiledQuery는 최소한 한번 이상 사용될 때에만 사용해야합니다.
    일반적인 LINQ to SQL 문장이 CompiledQuery 문장보다 더 빠릅니다. 왜냐하하면 CompiledQuery는 SQL Expression을 유지하고, 재사용하는 등의 모든 고려사항을 반영하기 위한 특별한 처리를 내부적으로 담고있기 때문입니다. 따라서 단순히 조회를 하는 일반적인 LINQ to SQL Expression 보다 무거울 수 밖에 없습니다.


Tag : ASP.NET

name    password    homepage
 hidden


XML 네임스페이스

XML로 만들어진 여러 마크업언어를 혼합하여 사용할 수 있는데, 그럴 경우 발생하는 문제가 바로 엘리먼트 이름의 충돌이다. 흔히 이런 류의 문제는 네임스페이스라는 것을 선언해서 해결하게된다.

  • xml에서 네임스페이스는 URI(Uniform Resource Identifier)형태로 제작된다. URI형태로 제작하는 것이, 기존의 네임스페이스와 새로 정의될 네임스페이스의 충돌을 최소화할 수 있기 때문이다.
  • xml로 제작된 각 마크업언어는 하나의 네임스페이스를 가질 수 있다. (물론 가지지않을 수 도 있다.)
  • XML Schema를 이용해서 마크업언어를 작성할 경우, 네임스페이스 값은 어떻게 할 것이며 네임스페이스를 반드시 선언해야하는냐 등을 정의 할 수 있는 문법을 제공한다. Schema에서 네임스페이스를 반드시 사용하도록 지정했다면, xml문서에서 해당 네임스페이스를 선언하고 사용해야한다.

네임스페이스 선언

  • 네임스페이스를 사용하도록 만들어졌다면, 각 엘리먼트의 접두사로 네임스페이스 명이 사용되어야한다. 하지만 URI형태로 제작된 네임스페이스를 필요할 때마다 사용하는 것은 비효율적이다. 그리고 네임스페이스 값 자체가, xml에서 사용하기 곤란한 문자들을 다수 포함하기에, 네임스페이스를 대신하는 별칭을 선언하여 사용하게 된다.
    <!--네임스페이스 선언-->
    <접두사:엘리먼트명 xmlns:접두사="네임스페이스명">

    <!--네임스페이스 사용-->
    <접두사:엘리먼트명></접두사:엘리먼트명>
  • 접두사의 작명규칙은 xml의 일반적인 작명규칙과 동일하다.
  • '접두사:엘리먼트명'은 QName(Qualified name)라고 하며, XML해석기는 QName을 하나의 엘리먼트명으로 간주하게 된다.
  • 네임스페이스를 선언하는 엘리먼트 부터, 그 엘리먼트의 모든 자식 엘리먼트까지 네임스페이스의 적용 범위가 된다.
  • 여러 네임스페이스를 선언하는 경우는 다음과 같다. 한가지 알아 둘 점은, 네임스페이스를 선언하는 엘리먼트가 무조건 해당 네임스페이스에 포함되는 엘리먼트가 아니여도 된다는 점이다. 즉, 하나의 루트 엘리먼트에 모든 네임스페이스 선언을 같이 해도 된다는 말이다.(그 루트엘리먼트가 선언하는 네임스페이스와 전혀 상관없더라도 말이다.) 다음 예제를 통해 알아보자.
    <!--
       여러 네임스페이스 선언
       루트엘리먼트는 A네임스페이스에 속하는 엘리먼트지만,
       루트엘리먼트에 다른 모든 네임스페이스를 선언하고있다.
       엘리먼트의 선언은 소속에 관계없이 어떤 엘리먼트에서도
       가능하지만, 사용은 반드시 소속엘리먼트에만 해야한다.
    -->

        
    <A:루트엘리먼트
          xmlns:A="A네임스페이스"
          xmlns:B="B네임스페이스"
          xmlns:C="C네임스페이스">
        <A:엘리먼트 />
        <B:엘리먼트>
           <B:자식엘리먼트 />
        </B:엘리먼트>
        <C:엘리먼트 />
  • Default Namespace : 하나의 마크업 언어를 사용할 경우, 굳이 네임스페이스를 위해 접두사를 모두 붙이는 것은 오히려 거추장스럽다. 이를 위해서 Default Namespace를 제공하고 있다.
    <!-- 
      Default Namespace는
      Namespace선언 시 접두사를 생략하면 된다.
    -->

    <엘리먼트명 xmlns="네임스페이스">
        <자식엘리먼트 />
    </엘리먼트명>
  • Default Namespace를 사용하면, 네임스페이스 범위의 모든 엘리먼트에 네임스페이스가 부여된 상태로 간주되는데, 네임스페이스에 속하지 않는 엘리먼트가 있을 경우나, 부분적으로 다른 네임스페이스에 속하는 엘리먼트가 올 경우 다음과 같은 문법을 사용해야한다.
    <!-- Default Namespace선언-->
    <루트엘리먼트 xmlns="네임스페이스">
        <!-- Default Namespace에 속하지 않는 엘리먼트-->
        <엘리먼트A xmlns="" />
        <!-- 다른 Namespace에 속하는 엘리먼트의 경우-->
        <엘리먼트B xmlns="네임스페이스B" />
    </엘리먼트>

    위에서, Default Namespace 범위안에 특정 엘리먼트들은 자신이 다시 네임스페이스를 선언함으로서, Default Namespace의 범위를 벗어났다. 그리고, 당연히 그 자식 엘리먼트들은 부모 엘리먼트의 영향을 받게 된다.
  • 속성과 Namespace : 속성도 Namespace의 적용을 받으므로, 접두사를 붙여야한다.
  • Default Namespace와 속성 : Default Namespace의 범위안에 속성은 Namespace의 적용을 받지 않는다. 따라서, 다음과 같은 방법으로 해결해야한다.
    <!-- 
    같은 네임스페이스 선언을 Default Namespace와 일반 Namespace방법 모두 선언함으로서, 속성이 Default Namesapce에 속하지 않는 문제를 해결한다. 속성은 Default Namespace에 속하지 않으므로, 속성 앞에는 접두사를 사용한다.
    -->

    <엘리먼트 
      xmlns="네임스페이스" 
      xmlns:접두사="네임스페이스">
        <자식엘리먼트 접두사:속성="값" />
    </엘리먼트>
  • XML Schema를 이용하여 새로운 마크업언어를 작성할 때, 네임스페이스 명과 네임스페이스에 대한 여러 옵션을 다룰 수 있지만, 여기서 그 내용을 기술하지는 않겠다.
Tag : XML

name    password    homepage
 hidden


DTD문서 작성법3 (Entity, 컨티셔널 섹션)

Entity

Entity는 보통 엔티티가 사용되는 위치나 엔티티내용이 외부파일로 존재하는가에 등에 의해 여러가지로 분류되어진다.

  • 내부 엔티티 : 내부 엔티티란 DTD문서 내에서 텍스트형태로 정의된 엔티티를 말한다. 내부 엔티티는 내부 일반 엔티티와 내부 파라미터 엔티티로 구분되는데, 그 차이는 엔티티의 사용영역에 따른다.
    - 내부 일반 엔티티 : 내부 일반 엔티티는 일반적으로 xml문서에서 사용되는 엔티티를 말하며, '&'로 시작하고 ';'으로 종료되는, 예를 들어 &엔티티명;과 같은 형태를 띤다. 엔티티의 정의는 DTD문서내에서 정의되며, 사용은 xml문서에서 사용하게 된다.
        DTD문서
        <!ENTITY 엔티티명 "엔티티내용">
        XML문서
        <!-- 아래와 같은 선언은 DTD문서의 엔티티내용으로 대체된다. -->
        &엔티티명;
    - 내부 파라미터 엔티티 : 내부 일반 엔티티와 차이점은 내부 파라미터 엔티티는 DTD문서 내에서 사용된다는 점이다. 중복되는 문장을 내부 파라미터 엔티티를 이용하여 보다 간편하고 간결하게 표현될 수 있다.
        DTD문서
        <!--엔티티선언-->
        <!ENTITY % 엔티티명 "엔티티내용">
        <!-- 엔티티사용-->
        %엔티티명;
  • 외부 엔티티 : 외부 엔티티란 엔티티의 내용 부분만 외부의 파일 형태로 저장된 것을 말한다.(파일 확장자 상관없음) 내부 엔티티와 마찬가지로 일반과 파라미터로 분류된다. 한가지를 제외하고 내부 엔티티와 모두 같다. 그 차이점은 엔티티를 선언할 때 다음과 같이 선언한다는 점이다.
        <!ENTITY 엔티티명 SYSTEM "엔티티경로">
        <!ENTITY % 엔티티명 SYSTEM "엔티티경로">
    즉 엔티티내용 부분을 엔티티 내용이 저장된 파일의 경로로 대체하면 된다.
  • 내장(Built-in) 엔티티 : 내장 엔티티란 XML에서 미리 정의되어 제공하는 엔티티들을 말한다. 이 엔티티들은 미리 예약되어 있으며, 사용자는 내장 엔티티를 사용만하면 된다. 대표적으로 자주 사용되는 내장 엔티티는 다음과 같다.

    엔티티

    대체될 문자

    &amp; 또는 &#x0026; &
    &lt; 또는 &#x003C; <
    &gt; 또는 &$x003E; >
    &apos; 또는 &#0027; '
    &quot; 또는 &#0022; "
    &#x20; 공백
    &#xd; 캐리지 리턴
    &#xa; 라인피드
    &#x9;
    &#92; \
  • 외부 일반 언파스드 엔티티 : Unparsed, 말그대로 XML파서나 응용프로그램이 해석할 수 없는 비문자 데이터에 대한 엔티티를 지정할 수 있다. 이 엔티티를 이용하기 위해서는 해당 비문자 데이터 타입에 대한 Notation이 먼저 정의되어있어야한다. Entitiy 정의할 때, 해당 비문자 데이터의 경로를 지정하고, 그 타입을 Notation으로 지정하면 된다.
        DTD파일
        <!-- 사용될 비문자 데이터의 타입을 Notation으로 지정-->
        <!NOTATION jpg SYSTEM "painter.exe">
        <!-- ENTITY에서 해당 비문자 데이터 지정 및, 해당 파일의 형식을 Notation으로 지정-->
        <!ENTITY myPicture SYSTEM "myface.jpg" NDATA jpg>
        <!-- 엔티티를 사용할 엘리먼트의 속성 정의-->
        <!ELEMENT person EMPTY>
        <!ATTLIST person image ENTITY #IMPLIED>
        XML파일
        <!-- 지정한 엔티티의 사용-->
        <person image="myPicture" />

컨디셔널 섹션(Conditional Section)

DTD문서 내에서, 어떤 특정 영역을 DTD문서의 내용으로 포함할 것인지 무시하도록 할 것인지를 결정할 수 있는 방법이 Conditional Section이라고 한다. 기본적으로 컨디셔널 섹션에서 사용되는 문법은 다음과 같다.

<![(INCLUDE | IGNORE) [
    <!--이 곳에 컨디셔널 섹션이 적용될 DTD를 작성하면된다.-->
]>

컨디셔널 섹션의 영역이 동작하지 말지를 결정하는 것은, 결정자가 IGNORE인지, INCLUDE인지에 따른다. 말 그대로, INCLUDE는 포함, IGNORE는 무시하겠다는 의미가 된다. 위에서 (INCLUDE | IGNORE) 위치에 INCLUDE 혹은 IGNORE를 위치시켜야한다. 보통 보다 유연하게 사용하기 위해, IGNORE와 INCLUDE를 엔티티로 정의해두고, XML문서에서 내부 DTD 서브셋을 이용, 컨디셔널 섹션을 조작하게된다. 아래에 DTD와 XML문서 내용 예제가 있다.

DTD문서 - test.dtd

<?xml version="1.0" encoding="utf-8"?>
<!ENTITY % section1 "IGNORE">

<!ELEMENT member (student*)>
    <!ELEMENT student (name, tel)>
        <!ELEMENT name (#PCDATA)>
        <!ELEMENT tel (#PCDATA)>

<!--컨디셔널 섹션 시작-->
<![%section1;[
    <!ATTLIST student gender (male| female) #REQUIRED>
]]>

XML문서 - test.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE test SYSTEM "test.dtd" [
    <!-- 컨디셔널 섹션을 포함하도록 한다. DTD내의 엔티티와 내부 DTD서브셋의
          엔티티가 중복될 경우 내부 DTD서브셋이 우선 적용된다.-->

    <!ENTITY % section1 "INCLUDE">
]>

<member>
    <student gender="male">
        <name>양현주</name>
        <tel>010-1111-1111</tel>
    </student>
</member>

Tag : DTD, XML

name    password    homepage
 hidden


DTD문서 작성법 2 (속성작성, 노테이션)

엘리먼트에 속성 만들기

엘리먼트에 속성을 만들기 위한 문법으로는 아래와 같으며, 아래의 ATTLIST엘리먼트를 구성하는 요소 중에서 엘리먼트명, 속성명, 속성타입, 디폴트 정의 등 하나라도 생략될 수 없다.

-DTD파일 예제
<?xml version="1.0"?>

<!-- 엘리먼트 정의 -->
<!ELEMENT 엘리먼트명 유형>

<!-- 엘리먼트에 대한 속성 정의 -->
<!ATTLIST 대상엘리먼트명
        속성명 속성타입 디폴트정의
        속성명2 속성타입2 디폴트정의2
        ...
        속성명n 속성타입n 디폴트정의n>

속성명 작성

속성명은 해당 엘리먼트에 부여되는 속성의 이름이 되며, 작명규칙은 아래와 같다.

  • 숫자나 '_'를 제외한 특수문자로 시작할 수 없다.
  • 공백이 이름에 포함될 수 없으며, 둘째 문자 부터 숫자와 '_', '-', '.', ':' 등의 특수문자 사용이 가능하다.

속성타입 작성

속성타입(Attribute Type)이란 속성이 가질 수 있는 데이터의 형태를 뜻하며, 그 종류는 아래와 같다.

  • CDATA : 단순한 문자데이터를 받을 경우 사용하는 유형이다.
        <!ATTLIST 엘리먼트명 속성명 CDATA 디폴트정의>
  • ID : 엘리먼트를 유일하게 구별할 수 있는 식별자를 지정하기 위해서 사용된다. ID를 속성타입으로 사용하게 되면 그 속성의 값은 그 XML문서의 ID값들 중에서 유일한 값만이 올 수 있다. 이 ID라는 속성의 DB에서 기본값과 같은 역할을 한다고 볼 수 있다. 이 ID 속성타입의 사용에는 약간의 제약사항이 존재한다.
    - ID속성은 하나의 엘리먼트에 하나만 존재할 수 있다.
    - ID속성의 값으로 공백이 포함될 수 없다.
    - ID속성의 값은 숫자로 시작할 수 없다.
        <!ATTLIST 엘리먼트명 속성명 ID 디폴트정의>
  • IDREF 또는 IDREFS : 해당 xml파일에서 ID 속성의 값만을 속성 값으로 받을 수 있는 속성타입이다. DB에서 외래키와 같다고 볼 수 있다. 
    - 이 속성타입은 이미 정의된 다른 ID값을 받기 때문에, ID와 제약사항이 같을 수 밖에없다.(즉 ID속성유형과 같이 속성값으로 공백이 포함될 수 없고, 숫자로 시작할 수 없다)0
    -  IDREF와 IDREFS의 차이점은 IDREF는 하나의 값만이 지정될 수 있지만, IDREFS는 여러 값들이 지정될 수 있다. 즉, IDREFS는 여러 ID값을 받을 수 있는데, 구분은 공백으로 한다.
        <!ELEMENT person EMPTY>
        <!ATTLIST person
            name ID #REQUIRED
            bestfriend IDREF #IMPLIED
            friends IDREFS #IMPLIED>
    위와 같이 DTD문서에 정의되어 있을 경우, person 엘리먼트의 속성은 다음과 같이 될 수 있다.
        <!-- IDREF와 IDREF값으로는 ID로 지정된 값만을 취할 수 있다. -->
        <person name="송준수" bestfriend="송준수">
        <person name="김수미" />
        <person name="고아라" bestfriend="송은영" />
        <person name="백승환" friends="고아라" />
        <!-- IDREFS는 여러 ID값이 지정될 수 있다.-->
        <person name="송은영" bestfriend="고아라" friends="백승환 고아라 김수미 송준수 송은영" />
  • NMTOKEN 또는 NMTOKENS : 작명규칙을 따르는 문자데이터형을 속성값으로 받을 수 있도록 한다. 작명규칙은 속성작명규칙과 같다. NMTOKENS는 공백으로 구분된 여러 값들을 받을 수 있도록 해준다.
  • 열거형(ENUMERATION) : 지정한 여러 속성값 중 하나를 선택할 수 있도록 하는 것이다.
        <!ATTLIST 속성명 (속성값1 | 속성값2 | 속성값n) 디폴트정의>
        <!ATTLIST occupation (student | professor | officer) #IMPLIED>
  • ENTITY 또는 ENTITIES : ENTITY값을 속성값으로 받을 수 있다. 하지만, 모든 엔티티값을 받을 수 있는 것은 아니다. 외부 일반 언파스드 엔티티, 즉 외부 파일로서 해석되지 않는 자료를 엔티티로 선언 했을 경우, 이 ENTITY로 지정한 속성의 값으로 받을 수 있다. ENTITIES는 ENTITY와 같지만 여러 값을 받을 수 있으며, 각 값들은 공백으로 구분된다.
        -DTD문서
        <?xml version="1.0"?>
        <!-- ENTITY에서 지정될 이미지에 대한 노테이션을 선언한다. -->
        <!NOTATION gif SYSTEM "painter.exe">
        <!-- 속성으로 사용될 외부 일반 언파스드 엔티티 선언 -->
        <!ENTITY SonPic SYSTEM "son.gif" NDATA gif>
        <!ENTITY KimPic SYSTEM "kim.gif" NDATA gif>
        <!--엘리먼트 선언-->
        <!ELEMENT people (person)*>
        <!ELEMENT person EMPTY>
        <!-- 속성 선언, ENTITY의 속성 타입을 사용했다.-->
        <!ATTLIST person
                name CDATA #REQURIED
                img ENTITY #REQUIRED>
        -XML문서
        <?xml version="1.0"?>
        <people>
            <!-- ENTITY타입의 속성인 img에 ENTITY값을 할당 -->
            <person name="손담비" img="SonPic" />
            <person name="김수로" img="KimPic" />
        </people>
  • NOTATION : Notation을 속성 값으로 받도록 할 수 있다.
    <!ATTLIST 대상엘리먼트명 속성명 NOTATION (노테이션명1 | 노테이션명2 | 노테이션명n) 디폴트정의>
    <!ELEMENT person EMPTY>
    <!ATTLIST person
           img CDATA #IMPLIED
          type NOTATION (gif | jpg) #IMPLIED>
    <!-- 위 DTD에 대한 xml파일 내용-->
    <person img="mypic.gif" type="gif" />

디폴트정의

속성의 Default값을 지정해주거나, 속성값을 생략하거나 반드시 기술하도록 정의하는 부분이다. 여기서 사용할 수 있는 값들은 다음과 같다.

  • Default 값 지정 : 속성 값 생략 시 기본적으로 지정될 데이터를 지정하면 됩니다. #IMPLIED, #FIXED와 같이 속성값을 생략할 수 있는 형태이다.
    <!ATTLIST 대상엘리먼트명 속성명 속성타입 "기본적으로 지정될 속성 값">
    <!ATTLIST person name EMPTY "Unknown">

    <!-- 생략 시 name속성의 값은 'Unknown'이 된다. -->
    <person></person>
  • #IMPLIED : 말 그대로, 속성을 생략할 수 있게 된다. <!ATTLIST 대상엘리먼트명 속성명 속성타입 #IMPLIED>
    <!ATTLIST person name EMPTY #IMPLIED>

    <!-- 생략 시 name 속성 값은 공란이 된다. -->
    <person></person>
  • #FIXED : 해당 속성값으로 고정값을 주고 싶을 때 사용합니다. 지정된 값 이외의 어떠한 값도 지정이 불가능하며, 그렇기 때문에 XML문서에서 속성값 작성을 생략할 수 도 있다.
    <!ATTLIST 대상엘리먼트명 속성명 속성타입 #FIXED "고정값지정">
    <!ATTLIST person occupation EMPTY #FIXED "Professor">

    <!-- 고정값 이외의 데이터는 기술 할 수 없다. -->
    <person occupation="Professor" />
    <!-- 생략 시 name 속성 값은 'Professor'가 된다. -->
    <person></person>
  • #REQUIRED : 속성값이 반드시 기술 되어야 하는 형태. 속성값을 생략할 수 없게 된다.

노테이션(NOTATION)

Notation이란 XML파서나 해석할 수 없는 데이터형으로, 해당 XML문서를 처리하는 애플리케이션이나 파서에게 특정 해석할 수 없는 비문자 데이터를 어떻게 처리하라는 지시자로 생각하면 된다. 비문자 데이터란, 그림, 동영상, 음악 등의 형태의 자료로서 이들 자료에 대해 xml에 기술할 때, 해당 자료를 해석할 수 있는 프로그램 명도 같이 지정해주는 것이 Notation의 역할이다. 사용방법은 매우 간단한데 아래와 같다.

<!NOTATION 노테이션명 PUBLIC "PUBLIC식별자" SYSTEM "데이터를 처리할 응용프로그램 경로">

위에서 PUBLIC "PUBLIC 식별자"는 생략이 가능하다. 다음은 PUBLIC식별자의 예이다.

<!NOTATION gif PUBLIC "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN" SYSTEM "painter.exe">

간단하게 다음과 같은 표현이 주로 사용된다.

<!NOTATION gif SYSTEM "painter.exe">

NOTATION이 사용되는 곳으로는 속성으로 기술되거나 외부언파스드엔티티를 위해 사용된다.

Tag : DTD, XML

name    password    homepage
 hidden


DTD문서 작성법 1 (엘리먼트가 가지는 데이터 유형 정의)

A사와 B사에서 정보전달을 위한 목적으로 XML을 사용하기로 했다. 하지만 어떻게 A사와 B사 모두 같은 문법을 사용한 XML문서를 작성하도록 할 수 있을까? 그것은 문법과 유형을 정의하고있는 DTD 문서를 작성하여, 두 회사에서 해당 DTD문서를 사용해 XML문서를 작성하게 하면 된다. 특정 DTD문서에서 정의한 문법에 어긋난 XML문서는 XML Parser가 해석할 때 에러를 출력하도록 할 수 있다..

텍스트 선언

xml문서와 마찬가지로 DTD문서의 최상단에는 텍스트 선언이라고 해서 다음과 같은 문장이 위치해야한다.(생략할 수 있다.)

<?xml version="버전" encoding="인코딩방식"?>
<?xml version="1.0" encoding="euc-kr"?>

생략시 Default 값은 '1.0', 'utf-8' 이다.

주석

<!-- -->로서 xml과 동일하다.

엘리먼트

xml 문서에서 사용할 엘리먼트를 선언하기 위해서는 <!ELEMENT>를 사용한다. xml은 대소문자를 구분하기 때문에, 'ELEMENT'는 반드시 대문자로 기술하여아한다.

<!ELEMENT 엘리먼트명 유형>

엘리먼트명의 작성 규칙은 다음과 같다.

  • 'xml', 숫자, 특수문자('_'문자는 제외)로 시작할 수 없다.
  • 두번째 문자 부터 '_', '.', '-' 문자와 숫자를 사용할 수 있다.(':' 문자도 사용할 수 있지만, 네임스페이스 선언과 중복되므로 사용을 권장하지 않는다.)
  • 공백이 포함될 수 없다.

유형에 사용될 수 있는 것들은 다음과 같다.

  • #PCDATA : 문자 데이터만을 가짐.
    '<!ELEMENT person (#PCDATA)>'는 xml문서에서 다음을 허용한다.
    <!-- CDATA섹션을 데이터로 가지는 엘리먼트-->
    <person><![CDATA[hellow]]></person>
      
  • EMPTY : 데이터를 가지지 않음.
    <!ELEMENT person EMPTY>
    이 유형을 가진 엘리먼트는 xml문서에서 다음과 같은 사용만 허용한다.
    <person></person> 또는 <person />
      
  • ANY : 모든 엘리먼트와 문자데이터를 가질 수 있음.
    '<!ELEMENT person ANY>'는 모든 엘리먼트와 데이터의 사용을 허용하게 된다.
      
  • 자식 엘리먼트 : 지정한 자식엘리먼트만 가질 수 있음.
    기술한 자식엘리먼트를 가질 수 있게 한다. 자식엘리먼트 리스트의 기술에는 패턴규칙이 적용될 수 있다. 즉, '?', '*'. '+'. '|', ','  등의 패턴과 결합해 다양한 표현을 할 수 가 있다.
    1. 반드시 기술한 순서대로 자식엘리먼트가 작성되도록 하는 ',' 연산자
        -DTD문서 내용
        <!ELEMENT person (name, gender)>
            <!ELEMENT name (#PCDATA)>
            <!ELEMENT gender (#PCDATA)>
        -XML문서내용
        <person>
             <name>이하늬</name>
             <gender>Female</gender>
        </person>
    2. 자식 엘리먼트의 반복 숫자를 제어할 수 있도록 해주는 '?', '*', '+' 연산자
      - ? : Zero or One
      - * : Zero or More
      - + : One or More
      의 의미를 가지고 있다. 따라서 다음과 같이 다양하게 표현할 수 있다.
        -DTD문서 내용
        <!ELEMENT person (name, age?, nickname+, (schoolname, graduated)*)>
            <!ELEMENT name (#PCDATA)>
            <!ELEMENT age (#PCDATA)>
            <!ELEMENT nickname (#PCDATA)>
            <!ELEMENT schoolname (#PCDATA)>
            <!ELEMENT graduated (#PCDATA)>
        -XML문서내용
        <person>
            <name>이시향</name>
            <age>16</age>
            <nickname>너구리</nickname>
            <nickname>이썅</nickname>
        </person>
    3. 리스트 중 하나만 선택해서 작성할 수 있도록 해주는 '|' 연산자
        -DTD문서 내용
        <!ELEMENT person (name, (brother|sister)*)>
            <!ELEMENT name (#PCDATA)>
            <!ELEMENT brother (#PCDATA)>
            <!ELEMENT sister (#PCDATA)>
        -XML문서내용
       
    <person>
            <name>정순영</name>
            <sister>정순화</sister>
            <brother>정순철</brother>
            <sister>정순지</sister>
        </person>
        
  • 혼합형태 : 아무 데이터나 자식을 가지지 않거나, 지정한 자식엘리먼트, 문자데이터 등 모두 가질 수 있는 형태
    <!ELEMENT person (#PCDATA | child1 | child2 | childN)*>
    위와 같이 사용할 수 있지만 다음과 같은 주의사항이 있다.
      - 문자데이터를 포함할 수 있도록 하기위해 #PCDATA는 반드시 젤 첫번째 위치에 존재해야한다.
      - 괄호 마지막에 '*'은 반드시 존재해야한다.
      - 리스트 사이에는 반드시 '|'연산자를 사용해야한다.
주의사항 : ANY나 EMPTY가 아닌 #PCDATA나 자식엘리먼트를 기술 할 때는 반드시 괄호'(', ')'에 포함되어야 한다.
Tag : DTD, XML

name    password    homepage
 hidden


XML 기초 2

엘리먼트

  • XML문서의 엘리먼트영역을 구성하는 요소들을 Element라고 하며, 모든 XML문서는 반드시 단 하나의 루트 엘리먼트를 필요로 한다.
  • 엘리먼트는 자식엘리먼트를 가질 수 있고, 엘리먼트 스스로 부가적인 정보를 나타내기 위해 속성(attribute)를 가질 수 있다.
  • 엘리먼트는 시작태그와 끝태그로 구성이 되며, 시작과 끝태그 사이에 내용(Content)가 오게 된다. 문자열 또는 다른 엘리먼트가 자식으로서 사용될 수 있다.
  • 엘리먼트는 반드시 내용을 가지지 않아도 되며, 이를 빈 엘리먼트라고 한다. 시작태그와 끝태그 사이에 아무 내용을 넣지 않아도 되지만, <엘리먼트명 />로 간단하게 표현할 수 도 있다.
  • 태그 작명 규칙
    • 첫글자는 문자(숫자 제외)나 '_' 문자로만 시작할 수 있다.
    • 특수 문자로는 두번째 글자 부터 '_', '-', '.', ':' 등을 사용할 수 있다.
    • 공백은 허용되지 않는다.
    • 대소문자를 구분한다.
    • 태그명은 xml로 시작할 수 없다.

주석

XML은 주석으로서 하나의 문법만 제공한다.

<!-- 내용 -->

주의할 점은 주석의 내용 중에 '--' 가 있어서는 안된다는 점이다.

공백 문자열과 CDATA섹션

스페이스 #x20, 탭 #x9, 캐리지 리턴 #xd, 라인 피드 #xa 등은 공백문자로서 이들 문자들은 공백문자 하나로 취급된다. 즉 여러 번의 탭과, 공백이라도 결국은 한번 뛰어쓴 것 처럼 출력된다는 의미이다.

CDATA(Character Data)와 비교되는 것으로는 PCDATA(Parsed Character Data)가 있는데, PCDATA는 해석된 문자 데이터라는 의미 그대로 XML 해석기에 의해 문자열 내부에 해석가능한 데이터들이 모두 처리되어 출력되어진다. CDATA는 해석기를 통하지 않고 바로 출력되기 때문에, 기술한 그대로 출력된다. 예를 들어 PCDATA에서 여러번 중복된 공백문자열은 하나의 공백으로 대체되는데, CDATA로 출력하게 될 경우, 모든 공백과 태그, 엔티티 등의 참조 값들이 그대로 출력된다.

<!-- CDATA 작성하기 -->
<![CDATA[  내용  ]]>

내부DTD Subset와 외부 DTD Subset

XML에서 새로운 마크업 언어를 DTD를 이용하여 작성하게되는데, 이 DTD를 XML문서 내부 또는 별도의 파일로 둘 수 있게 된다. 보통 DTD는 별도의 파일로 작성되며 다수의 xml문서가 하나의 DTD를 참조하는 형태를 띠게된다.

다음은 외부 DTD의 예제이다. 보통 xml을 이용하여 마크업언어를 작성할 때는, 외부 DTD를 이용하게 된다.

<?xml version="1.0"?>
<!-- DTD 선언 -->
<!DOCTYPE booklist SYSTEM "booklist.dtd">
<!-- 루트엘리먼트 시작 -->
<booklist>
    <book>
        내용
    </book>
</booklist>

DOCTYPE라는 엘리먼트를 이용하여 DTD를 선언하게 되는데, DOCTYPE 사용 문법은 다음과 같다.

- PUBLIC DOCTYPE 식별자
<!DOCTYPE 최상위엘리먼트명 PUBLIC 
        "(비공인||공인 기관)//DTD 개발 기관 이름//DTD명 및 버전//사용된 언어"
        "DTD문서의 경로">

- SYSTEM DOCTYPE 식별자
<!DOCTYPE 최상위엘리먼트명 SYSTEM
        "DTD문서의 경로"
>

  • 'PUBLIC' 또는 'SYSTEM' 식별자의 차이점 : 공개되에 누구나 사용되는 DTD문서일 경우 PUBLIC를 사용하고, 내부적으로, 제한적으로 사용되는 DTD의 경우 SYSTEM 키워드를 사용하면된다.
    '최상위엘리먼트명'
    의 경우 굳이 최상위 명과 일치하지 않더라도 에러를 야기하지 않으나, 일치시키는 것이 권장된다.
  • '(비공인||공인 기관)'의 위치에는 DTD문서를 개발하고 관리하는 기관이 국제적으로 공인되었는지 아닌지에 따라, '+'혹은 '-'기호를 사용하면된다. 공인된 단체에서 작성된 DTD일 경우 '+', 비공인기관의 DTD일 경우 '-'이다.
  • '문서작성에 사용된 언어'의 경우 DTD문서가 작성된 언어의 국가 명을 기술하는 것으로서, 예를들어 영어로 작성된 경우 EN(대부분의 경우 해당)이 된다.
  • 'DTD주소'는 실제 DTD 문서의 경로가 위치하는 곳이다. PUBLIC DOCTYPE 식별자에서는 'DTD문서의 경로'가 생략될 수 도 있지만, 애플리케이션이나 브라우져에서 PUBLIC 식별자를 제대로 인식하지 못하는 경우를 대비하여 'DTD문서의 경로'를 기입할 수 도 있다.

실제로 DOCTYPE선언 예제는 다음과 같다.

<!DOCTYPE HTML PUBLIC
        "-//W3C//DTD HTML 4.01 Transitional//EN"
        "
http://www.w3.org/TR/html4/loose.dtd">

<!DOCTYPE booklist SYSTEM "booklist.dtd">

내부 DTD를 사용하는 경우는 대부분 몇몇 규칙을 새로이 또는 다시 정의 하기 위해서 사용된다. 재정의할 내용은 위에서 설명한 DOCTYPE엘리먼트에서 닫기태그 전에 대괄호('[', ']')안에다 재정의 내용을 기술 하면 된다. 다음은 내부 DTD의 예제이다.

<?xml version="1.0"?>
<!-- 내부 DTD 시작 -->
<!DOCTYPE booklist [
     <!--DTD내용 기술 (보통 재정의할 내용 기술)-->
    <!ELEMENT booklist (book)+>
    <!ELEMENT book (#PCDATA)>
]>

<!-- 내부 DTD 끝 -->

 

<?xml version="1.0"?>
<!-- 내부 DTD 시작 -->
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN"
      "http://www.wapforum.org/DTD/wml_1.1.xml" [
     <!--DTD내용 기술 (보통 재정의할 내용 기술)-->
     ......................
]>

<!-- 내부 DTD 끝 -->

Tag : XML

name    password    homepage
 hidden


XML 기초 1

XML 이란?

  • 확장가능한 마크업 언어(Extensible markup Language)
  • Markup Language란, 문서의 내용에 추가적인 정보를 표시할 수 있는 언어를 뜻한다. 각 태그Markup이 되며, 태그에 포함된 내용들에 관한 추가적인 정보를 표현하는 역할을 한다.
  • Extensible에서 의미하는 바와 같이, XML은 필요에 따른 새로운 Markup Language를 생성할 수 있는 메타 언어이다. 메타 언어란, 다른언어를 기술하거나 분석하는데 쓰이는 언어라는 의미이다. 즉 XML을 이용해 문서를 작성한다라는 뜻은, XML로 제작된 언어로 문서를 작성한다는 의미로 보면 된다.
  • 메타언어에는 SGML(Standard Generated Markup Language)이 대표적이다. SGML로 만들어진 언어는 HTML이 있으며, XML은 SGML을 보다 단순하고 사용하기 쉽도록 한 언어로 보면된다. 즉 XML은 SGML의 부분집합이다.
  • XML은 데이터 전달을 목적으로 많이 사용되는데, 예를 들어 특정 언어에서 다른 언어, 다른 시스템으로 데이터를 전송하는데 있어서 가장 보편적으로 사용되고 있다. 즉 특정분야의 필요에 맞게 XML을 이용하여 언어를 만들고, 그 언어 규격에 맞게 XML을 이용해 서로 데이터를 전송하고 관리할 수 있게 된다. 특정 프로그램에서 다른 프로그램, 출판 분야, 고객 정보 관리, 데이터베이스 관리, 백업 등 데이터를 다루는 거의 모든 분야에서 사용가능하며 사용되어지고 있다.
  • XML이 HTML을 대체할 수 있다고 생각하는 사람이 있는데, XML과 HTML은 서로 다른 분야로서, XML이 HTML이 하는 역할을 할 수 없고, HTML이 XML의 기능을 대신할 수 없다.
  • Well- Formed XML Document : W3C의 XML 1.0권고안의 문법을 잘 지켜서 작성된 문서를 말한다. XML은 HTML과 달리 문법을 잘 지켜서 작성해야하며 그렇지 않을 경우, XML문서로 취급되지 않으며 작동하지 않는다.
  • Valid/Invalid Document : XML로 만들어진 특정 Markup Language에 맞게 작성된 문서이다. 'XML 문서에 대해 유효성 검사를 한다'라는 것은 XML로 개발된 특정 언어의 규칙과 구조에 맞는지 검증한다는 의미이다.

XML 문서 구조

  • Prolog : XML선언 및 문서 유형 선언(DTD::=Document Type Definition), 프로세싱 지시자(Processing Instruction)가 이 영역에 포함될 수 있다.
  • Element : 하나의 루트 엘리먼트와 하위 엘리먼트로 구성된다.
  • Misc : 문서 마지막에 위치하며 보통 생략되는 부분으로서 주석이나 Processing Instruction 등이 위치하는 경우가 많다.

XML 선언

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

  1. 이 문장은 생략될 수 있지만, 기본적으로 xml문서에 기술되는 것이 권장된다.
  2. 반드시 문서 첫번째 라인에 위치해야하며, 주석도 이 문장 이전에 위치할 수 없다.
  3. '<?xml' 사이에 공백은 허용되지 않는다.
  4. encoding부분은 생략될 수 있으며, default는 UTF-8이다. 실제로 문서의 인코딩 타입과 일치하지 않을 경우 에러를 출력한다.
  5. standalone부분은 dtd부분이 xml문서에 포함되는건지, 외부 dtd를 참조하는건지에 따라 yes 또는 no를 설정하면 된다. 생략 가능한 부분으로 default값은 no로 작동된다. 이 부분을 생략하고 dtd부분을 xml문서에 포함 시켜도 아무 문제가 없으므로, 대부분의 경우 생략되는 부분이다.

기초문법

  • XML을 사용하기 위해 기본적으로 알야아하는 문법으로서 EBNF(Extended Backus-Naur Form)가 있다.

Symbol ::= Expression

  • CharA ::= [a-zA-Z0-9]은 CharA는 대소문자 a부터 z까지, 숫자 0부터 9까지 중 하나의 문자라는 의미이다.
  • 문자 표현은 ' 또는 " 문자 사이에 위치해야하며 대소문자를 구별한다.
  • 패턴 결합을 통해 보다 다양하고 복잡한 형태의 EBNF를 사용할 수 있다.
    • A : One, A표현은 한번만 기술되어야 한다.
    • A? : One or Zero, A표현은 기술되지 않거나 한번만 기술되어야 한다.
    • AB : A and B, A표현식과 B표현식은 순차적으로 기술되어야 한다.
    • A|B : A or B, A표현식과 B표현식 중 하나만 표현되어야 한다.
    • A-B : A without B, B표현식에 일치하지 않는 A표현식
    • A+ : One or More, A표현식은 1번 이상 기술 되어야 한다.
    • A* : Zero or More, A표현식은 기술되지 않거나 하나 이상 표현될 수 있다.

Version ::= 'version ' vnumber

vnumber ::= [a-zA-Z0-9.]+

  • 위의 표현식은 다음과 같다.
    Version = 'version 1.0z'
Tag : ebnf, XML

name    password    homepage
 hidden


IIS버전

IIS 버전 간의 중요한 차이점이 요약되어 있습니다.



IIS 4.0 IIS 5.0 IIS 5.1 IIS 6.0

플랫폼

Windows NT 4.0

Windows 2000

Windows XP Professional

Windows Server 2003 제품군

아키텍처

32비트

32비트

32비트 및 64비트

32비트 및 64비트

응용 프로그램 프로세스 모델

TCP/IP 커널

MTX.exe

TCP/IP 커널

DLLhost.exe(중급 또는 고급 응용 프로그램 격리에서의 다양한 DLL 호스트)

TCP/IP 커널

DLLhost.exe(중급 또는 고급 응용 프로그램 격리에서의 다양한 DLL 호스트)

HTTP.sys 커널

IIS 5.0 격리 모드에서 IIS를 실행할 경우: Inetinfo.exe(In-process 응용 프로그램의 경우) 또는 DLLhost.exe(Out-of-process 응용 프로그램의 경우)

Worker Process Isolation Mode에서 IIS를 실행할 경우: W3wp.exe(여러 개의 작업자 프로세스)

메타베이스 구성

이진

이진

이진

XML

보안

Windows 인증

SSL

Windows 인증

SSL

Kerberos

Windows 인증

SSL

Kerberos

보안 마법사

Windows 인증

SSL

Kerberos

보안 마법사

Passport 지원

원격 관리

HTMLA

HTMLA

HTMLA 없음

터미널 서비스

원격 관리 도구(HTML)

터미널 서비스

클러스터 지원

Windows NT 4.0 사용

IIS 클러스터링

Windows 지원

Windows 지원

WWW 서비스

Windows NT 4.0의 IIS

Windows 9x의 개인 웹 관리자

Windows 2000의 IIS

Windows XP Professional의 IIS(선택 사항)

[출처] IIS 버전|작성자 삐꾸

Tag : IIS

name    password    homepage
 hidden


PHP를 배우시려면 여기로 가세요.
지난 몇 주동안 PHP를 배우기위해 노력했었습니다. 처음 PHP강좌나 이런 문서를 많이 검색 했었는데, 네이버나 다음의 경우 광고 페이지만 나오더군요. 제가 사용한 검색어는 'PHP강좌' 이런식이었습니다. 이런 광고 페이지와 씨름하며, 열심히 비효율적으로 PHP를 몇주간 공부하다가 우연히 'PHP매뉴얼'이라고 검색하니 바로 PHP를 공부하기 좋은 사이트들이 나오더군요.
머리가 나쁘면 몸이 고생한다는 말을 다시한번 깨닫게 되었습니다.
여러 좋은 버전이 많이 있지만, PHP공식 사이트에서 한글 매뉴얼을 지원하니, PHP를 공부하기 위해서는 여기가 좋을 듯합니다.
http://www.php.net/manual/kr/index.php

Tag : PHP 강좌
Commented by Favicon of http://www.beneglo.com BlogIcon BENEGLO at 2008.07.28 19:40 신고  r x
저도 관련 함수가 있는지 찾을 때 자주 사용합니다 ^^

name    password    homepage
 hidden


PHP에서 Form값 전달받기

Get, Post에 대한 간략한 설명

웹에서 Form에 입력된 데이터를 전송하는 방법에는 두가지가 있습니다. Get과 Post방법인데요, 이 둘다 각 자 특징과 장단점이 존재하기에 상황에 따라 선택적으로 사용되어집니다.

  1. Get : 이 방법은 웹 주소 뒤에 데이터를 붙여서 전송하는 방법입니다. Get은 Post보다 빠르지만, 보통 데이터의 전송량이 Post방식보다 작고, 웹 주소에 데이터가 노출되기에 누구나 전송되는 데이터를 볼 수 있습니다. 따라서 아이디나 패스워드를 Get방식으로 전송하는 것은 옳바르지 못합니다.
    하지만 Get방식은 주소에 데이터가 포함되어 있기때문에, 해당 페이지를 그대로 북마크할 수 있으며, 주소만 저장해둬도 해당 페이지를 그대로 재방문할 수 있다는 점입니다.
  2. Post : Post방식은 HTTP 헤더에 전송데이터를 포함시켜 전송하는 방법입니다. 주소가 노출되지 않기 때문에 아이디, 패스워드 또는 노출되지 말아야할 정보를 전송하는데 적합한 방식입니다.
  3. 위의 Get과 Post방식을 정하는 방법은 다음과 같습니다. 예를 들어 Post를 사용한다고 하면 아래와 같습니다. Get을 사용하고 싶다면, Post를 Get으로 변경하면됩니다.

<form method="post" action="receive.php">
  Name : <input type="text" name="name">
  <input type="submit" value="Send">
</form>

PHP에서 Form값 전달하기

전송된 데이터를 전송받는 방법은 두가지로 나뉩니다.

  1. 이전 버전의 PHP에서는 Post나 Get으로 전송된 데이터를 자동으로 변수화하기 때문에, 바로 일반 변수처럼 사용할 수 있었습니다. 하지만, 이로인한 보안 문제가 발생하면서 이 방법이 기본적으로 Disabled되었고 'register_globals=Off'라는 옵션이 php.ini파일에 추가되었습니다.  이 옵션의 값을 Off에서 On으로 변경하였을 시, 예전처럼 PHP가 전송되어져 온 값을 자동으로 변수화 합니다.
        echo $name; //전송된 name값을 바로 사용할 수 있다.
  2. PHP 4.X 버전 부터는 'register_globals=Off' 옵션이 추가되고, 옵션값이 off인 상태에서는 전송된 값을 바로 변수처럼 쓸 수 없습니다. (이 방법이 더 권장되고있습니다.)
    대신 다음과 같이 전송된 데이터를 읽어들일 수 있습니다.
        $HTTP_GET_VARS['name']; 또는 $_GET['name'];
        $HTTP_POST_VARS['name']; 또는 $_POST['name'];
    체크박스와 같이 배열로 데이터가 전송되어야 하는 경우 다음의 경우를 조심합니다.
    - checkbox나 select문의 name 속성 값을 줄 때 마지막에 '[]'를 붙여주어야합니다. 그렇지 않은 경우 모든 데이터가 배열로서 전송되지 않습니다.
    - 받을 때는, $_GET[이름][첨자]로 참조합니다.
    소스는 다음과 같습니다.

send.html

<form method="get" action="receive.php">
    Favorites : <br>
    <select name="favorites[]" multiple>
        <option>Internet Surfing
        <option>Playing Games
        <option>Reading books
    </select>
    <input type="submit">
</form>

receive.php

<?
    $size = count($_GET[favorites]);

    for($i =0; $i < $size; $i++)
        echo $_GET[favorites][$i] . "<br>";
?>

Tag : php
Commented by Favicon of http://grrfruity.blogspot.com/ BlogIcon grrfruity at 2010.02.01 13:08 신고  r x
옛날 서적을 가지고 공부하다 보니까 좀 문제가 많이 생기는 군요. 한참 해매다가 덕분에 겨우 해결할 수 있었네요.

name    password    homepage
 hidden


 Category
분류 전체보기 (95)
Netwrok & Security (6)
Web Development (61)
Database (5)
Framework (6)
Others (17)
About (0)
 TAGS
: ajax Android APM application error #401 ASP ASP.NET asp.net ajax ASP.NET Machine at ATRIX ATX ATX와BTX의차이 Auto-Negotiation back-end bash shell Bit ending Blog API BTX c#.net CentOS class id 차이 CSMACD data tier Database DB DB동작원리 DB처리과정 DTD ebnf ethereal ethernet exception firefox2 설치 font-family Framework과 자동로그인 front-end FTP get post 우선순위 hotmail
 Calendar
«   2018/11   »
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30  
 Visitor Statistics
Total : 269,586
Today : 14
Yesterday : 14
rss