오늘날에는 XML을 사용하는 것을 매우 당연한 것으로 여긴다. 어디에서나 XML을 사용한다. 그러나 뒤로 물러나서 살펴보면 XML이 강력한 기술이라는 사실을 알 수 있다. IDE를 이용하면 XML 트리를 쉽게 빌드할 수 있다. 또한, 몇 가지 유효성 검증 기술을 이용하면 XML 코드가 올바른지 확인할 수 있다. XSLT는 전용 XML 변환 언어이다. ActionScript용 E4X와 같은 언어의 구문에 직접 내장될 수 있다.
그렇지만 XML에는 부정적인 면이 있다. XML을 잘못 사용할 수 있다는 점이다. XML은 엉망이 될 수 있다. 매우 복잡해질 수도 있다. 불완전하게 정의될 수도 있다. 또한, 단지 다루기 어려운 일반 텍스트가 될 수도 있다. 그렇다면 이처럼 강력한 기술을 효과적으로 사용하려면 어떻게 해야 할까? 이 기사에서는 독자가 올바르게 작업을 수행하여 사용하기 쉬운 XML을 빌드할 수 있게 도와주는 10가지 특정 규칙을 제시한다.
필자는 XML 코드를 .xml 확장자로 된 파일에 저장하는 경우를 매우 많이 보았다. 이러한 확장자는 쓸모가 없다. 이러한 확장자에는 필자가 "cat"으로 파일의 내용을 확인해도 바로 알 수 없는 정보가 포함되어 있지 않다. 태그를 보는 순간에 그 코드가 XML이라는 것을 알게 될 뿐이다. 그 대신 고객에게 의미가 있는 확장자를 사용한다. 그리고 궁극적으로 Google에서 검색될 때 Google 검색에서 문서에 대한 링크나 XML 파일 형식의 일부 예제를 리턴할 수 있게 고유한 확장자를 사용한다.
일부 XML에서 발견한 또 다른 문제는 루트 태그가 <xml>이라는 점이다. 마찬가지로 이 태그에는 아무런 정보도 없다. 파일 안에 무엇이 있을까? 이 파일이 담당자 목록이라면,
루트 노드는 <contacts>이 되어야 한다. XML은 사용자가 읽을 수 있게 되어 있어야 하므로 비즈니스 문제와 밀접하게 관련된 태그 이름과 속성 이름을 사용해야 한다. 루트 노드가
<contacts>이면 필자는 그 안에 <contact> 태그와 <first>, <middle>, <last> 등으로 된 <name> 태그가 있을 것으로 예상한다.
너무 일반적이거나 특정 언어에 적합한 구문을 사용하지 않는다.
이러한 XML을 지속성 형식이라고 한다. 그리고 대부분의 언어에는 데이터 구조를 XML로 계속해서 유지할 수 있는 방법이 있다. 적어도 XML을 읽거나 쓰는 프로세스만큼은 분명히 동일한 언어로 수행된다면, 괜찮다. 그러나 그러한 경우는 거의 없다. 애플리케이션에서 무언가를 파일에 쓰려고 하는 경우, 어떤 시점에서는 사용자가 이 파일을 읽거나 일부 애플리케이션에서 또 다른 언어로 이 파일을 읽을 가능성이 있다.
필자가 하고 싶은 말은 XML에서는 특정 언어에 적합한 구문을 사용하지 말라는 점이다. <data type="NSDate">07-18-2010</data> 구문을 자주 보았을 것이다. NSDate는 무엇일까? 이것은 애플리케이션의 플랫폼에
있는 날짜의 클래스 이름이다. 그러면 플랫폼이나 언어를 변경하면 어떻게 될까? 어떤 것이든 예상되는 새 플랫폼과 NSDate 태그 사이를 이동할 변환 계층이 필요하게 된다.
XML에서 특정 언어에 적합한 구문을 사용하지 말고 <date>…</date>와 같은 단순한 구문을 사용한다. 이렇게 하는 것이 사용자가 읽을 수 있고 이해하기 쉬우며
특정 언어나 프레임워크에 의존하지도 않는다.
이 단계에서 또 다른 중요한 교훈은 XML을 너무 일반적 형태로 작성하지 말라는 점이다. 목록 1에서 이와 관련된 간단한 XML 예제를 살펴보자.
목록 1. 일반적인 노드 트리
<nodes>
<node type="user">
<node type="first">jack</node>
</node>
</nodes>
|
이것이 무엇을 의미할까? 필자는 이 코드가 사용자 목록이라고 이해했다. 그러나 이 코드는 사용자가 읽기에 쉽지 않으며 편집하기도 어렵다. 게다가 XSLT와 같은 도구로 XML을 사용하거나 참으로 어려운 스키마를 사용하여 코드의 유효성을 검증한다. 사실상 이 XML 코드가 의미하는 것은 목록 2와 같다.
목록 2. 개선된 노드 트리
<users>
<user>
<first>jack</first>
</user>
</users>
|
이 코드가 더 낫지 않은가? 이 코드에는 의미하는 바가 나타나 있으며 이 코드는 바로 전달하고자 하는 내용을 의미한다. 이 코드는 읽기 쉬우며 구문 분석하기도 어렵지 않다. 또한, 유효성을 검증하기 쉬우며 XSLT를 사용하여 변환하기도 수월하다. 게다가 코드도 훨씬 더 작다.
"디스크 공간의 가격이 싸져서 10센트면 테라 바이트의 공간을 확보할 수 있다"라고 말할 수도 있다. 물론 그렇다. 그리고 분명히 기가 바이트의 XML 파일을 작성할 수도 있다. 그러나 프로그래밍은 전적으로 상충관계(Tradeoff)에 의존한다. 시간을 확보하기 위해 공간이나 메모리를 희생할 수 있다. 그러나 XML 파일의 크기가 큰 경우에는 두 가지 상황이 모두 악화된다. 드라이브에 있는 파일의 용량이 크면 구문 분석을 하여 유효성을 검증하는 데 걸리는 시간이 길어진다. 그리고 대용량 파일은 트리를 빌드하는 데 시간이 오래 걸리고 메모리를 많이 사용하기 때문에 DOM 기반 구문 분석기를 사용하는 데 방해가 된다.
그렇다면 대안은 무엇일까? 한 가지 가능성 있는 대안은 파일을 여러 개 작성하는 것이다. 하나의 파일은 색인 역할을 하도록 하고 다른 파일에는 모든 XML 클라이언트에서 사용할 수 없는 대용량 자원을 저장한다. 또 다른 대안은 파일에 있는 모든 대용량 CDATA 청크를 완전히 XML 외부로 이동하여 고유 형식으로 된 자체 파일에 저장하는 것이다. 모든 데이터를 함께 유지할 경우에는 모든 파일을 새로운 확장자로 된 새 파일로 압축한다. 일반적으로 사용하는 모든 언어에는 파일을 빠르고 쉽게 압축하고 압축 해제할 수 있는 모듈이 있다.
반드시 필요한 경우가 아니면 네임스페이스를 사용하지 않는다.
네임스페이스는 XML 어휘부의 유용한 부분이다. 네임스페이스를 이용하면 확장 가능한 파일 형식을 쉽게 제공할 수 있다. 애플리케이션에 필요한 것이면 어떤 것이든 그것에 적합한 기본 태그 세트를 정의할 수 있으며 고객은 트리를 혼란스럽게 하지 않으면서 자체 데이터를 자신의 네임스페이스에 있는 파일에 추가하는 것도 가능하다.
그렇긴 하지만, 네임스페이스를 사용하면 구문 분석하고 데이터를 관리하기가 매우 어려워진다. E4X와 같은 언어 확장에서 네임스페이스를 사용하면 혼동될 수 있다. 네임스페이스는 XSLT에서 XML을 사용하기 어렵게 한다. 그리고 네임스페이스를 사용하면 XML을 읽기가 훨씬 더 어려워진다.
그러므로 반드시 필요한 경우에만 XML 네임스페이스를 사용해야 한다. XML에서는 당연히 네임스페이스를 사용해야 하는 것처럼 네임스페이스를 사용해서는 안 된다. 네임스페이스를 사용하지 않아도 XML은 제대로 작동한다.
이러한 모든 규칙을 적용하면 XML을 이해하기 쉽고 간단하고 깔끔하게 유지할 수 있다. 이런 점에서 XML 스펙에서 많은 것들이 허용되는 경우에도 이러한 것들을 반드시 사용할 필요는 없다고 할 수 있다. 예를 들면, 요소와 속성 이름에서 대시를 사용할 수도 있다. 그러나 이렇게 하면 E4X와 같은 언어 확장에서 그러한 XML을 사용하기가 훨씬 더 어려워진다. 문제는 그렇게 하는 것이 가치가 있느냐는 점이다.
필자는 요소나 속성 이름에 특수 문자를 사용하지 말 것을 권장한다.
XML을 구문 분석하기는 어렵다. XML을 안전하게 구문 분석하기 위해, 태그나 속성을 찾는 코드가 이러한 태그나 속성을 찾지 못하고 정상적으로 종료하지 않도록 하려면 많은 노력이 필요하다. 따라서 코드는 더 늘어나고 복잡해지며 정확하게 집중해야 할 실제 비즈니스 논리가 불명료해진다. 그렇다면 이러한 문제를 어떻게 피할 수 있을까? XML을 사용하기 전에 XML의 유효성을 검증해야 한다. 이를 위해 몇 가지 표준을 사용할 수 있다. DTD(Document Type Definition)나 XML 스키마를 지정할 수 있다. (DTD와 XML 스키마에 대한 자세한 내용은 참고자료를 참조한다.) 필자는 개인적으로 XML 스키마가 다루기 편하지만 XML 스키마를 처음 다루는 경우라면 몇 가지 다른 유효성 검증 시스템을 사용해 볼 것을 권장한다.
여기서 얻을 수 있는 큰 장점은 일단 XML의 유효성이 검증되면 XML에 의존할 수 있다는 점이다. 애플리케이션에서 내부적으로 읽고 쓰는 것을 처리하는 작업이 가치가 없을 수도 있다. 그러나 XML을 또 다른 애플리케이션으로 생성하거나 직접 작성하는 경우에는 이렇게 하는 것이 매우 유용하다.
파일에 저장된 XML이 결과적으로 파일 형식이 된다는 사실을 간과하기 쉽다. 어떤 형식으로든 파일에 포함되어야 하는 가장 중요한 것 중 하나는
파일 버전 번호이다. 다음과 같은 형태로 쉽게 추가할 수 있다. <customers version="1">...</customers>. 그리고 파일을 읽는 코드에서 버전 번호가 파일의
현재 버전보다 작은지 또는 같은지 확인해서 버전 번호가 현재 버전과 같지 않으면 예외를 처리한다. 이렇게 하면 나중에 코드 버전이 변경되는 경우에도
이전 버전을 새 태그와 혼동하지 않게 된다. 물론 계속해서 애플리케이션을 개발하게 되면 해당 파일의 이전 버전을 모두 지원해야 한다.
엔지니어는 매우 게으르다. 필자가 엔지니어이기 때문에 이렇게 말하는 것이다. 그러나 독자 역시 엔지니어이다. 프레임워크에서 개발자를 위한 XML을 내보낸다고 하면 엔지니어는 "그 정도면 충분해요"라고 말할 것이다. 그러나 XML을 빌드하는 프레임워크는 일반적으로 매우 좋지 않다. 예를 들면, 목록 3과 같은 것을 얻을 가능성이 있다.
목록 3. 사용자 목록
<users>
<user>
<id>1</id>
<first>jack</first>
</user>
</users>
|
그렇다면 <id>가 정말 태그가 되어야 할까? 필자는 id가 속성이 되어야 한다고 생각한다. id는 간결하며 다소 간단한 XPath(/users/user[@id=1])를 사용하여 id로 사용자를 쉽게
찾을 수 있다.
이 사용자 목록이 사용자가 읽을 수 있는 파일이 되려면 목록 4에서와 같이 속성을 적절하게 사용해야 한다.
목록 4. 개선된 사용자 목록
<users>
<user id="1">
<first>jack</first>
</user>
</users>
|
프레임워크에서 목록 3을 생성하는 이유를 알 수는 있지만, 노드를 사용하는 것이 언제나 더 안전하다. 그러나 속성을 사용하면 DOM 트리에서 중요한 요소를 식별하는 것이 가능하므로 속성을 사용해야 한다.
XML에서는 특정 문자(",&,<,> 등)를 사용하는 데 여러 가지 제약이 있다. 그러나 실제로는 이러한 문자를 많이 사용한다. 따라서 XML에 안전한 인코딩으로 모든 문자를
변환해야 하거나 텍스트, 코드 등으로 구성된 큰 영역을 CDATA 블록에 삽입해야 한다. 개발자는 CDATA를 사용하면 구분 분석하기가 더 어렵다고 생각하기 때문에
CDATA를 사용하지 않으려고 하는 것 같다. 그러나 CDATA 섹션이 다른 어떤 것보다 구분 분석을 더 어렵게 하지는 않으며 대부분의 DOM 구문 분석기는
CDATA 섹션을 간단히 변환하므로 개발자는 이러한 과정을 전혀 신경 쓸 필요가 없다.
CDATA를 사용하는 또 다른 중요한 이유는 정확하게 형식화된 데이터를 유지하는 데 있다. 예를 들어, Wiki 형식에서는 이러한 문자에 특히 주의해야 하기 때문에
Wiki 페이지를 내보내는 경우에는 리턴 및 줄 바꾸기와 같은 문자의 정확한 위치를 계속 유지해야 한다.
그렇다면 CDATA를 항상 사용해서는 안 되는 이유는 무엇일까? 그 이유는 CDATA를 사용하면 문서를 읽기가 훨씬 더 어려워지기 때문이다. 그리고 CDATA가 불필요한
경우에는 CDATA가 특히 방해가 된다. 따라서 CDATA를 사용하되 해당 XML 형식으로 작성하여 사용하고 특수 문자가 있을 것으로 생각되는 데이터에서는 그 형식을
유지해야 한다. 그러나 그 외에는 CDATA를 사용하지 말아야 한다.
이제까지 엄격한 형식으로 된 XML 문서에 관해 살펴보았다. 필자는 구조를 엄격하게 적용하는, XML 스키마와 같은 유효성 검증기를 사용할 것을 권장하기도 했다. 이렇게 하는 데는 합당한 이유가 있는데 그것은 구조화된 데이터가 구문 분석하기 쉽기 때문이다. 그러나 다소 유연성이 필요하면 어떻게 해야 할까? 옵션 데이터를 해당 노드 내에 있는 옵션 블록에 삽입할 것을 권장한다. 예를 들어, 목록 5를 살펴보자.
목록 5. 클러스터화된 사용자 레코드
<users>
<user id="1">
<first>jack</first>
<middle>d</middle>
<last>herrington</last>
<runningpace>8:00</runningpace>
</user>
</users>
|
이 XML 코드에는 사용자와 관련된 모든 데이터 외에도 더 많은 것들이 포함되어 있다. 그런데 first, middle 및 last는 필요한 이유를 알겠는데 'runningpace'는 왜 있을까? runningspace가 필요할까? 이러한 필드가 많이 있게 될까? 이 필드를 확장할 가능성이 있을까? 모든 질문에 대한 대답이 예이면 목록 6과 같은 XML을 사용할 것을 권장한다.
목록 6. 잘 구조화된 사용자 레코드
<users>
<user id="1">
<first>jack</first>
<middle>d</middle>
<last>herrington</last>
<userdata>
<field name="runningpace">8:00</field>
</userdata>
</user>
</users>
|
이 방법을 사용하면 호스트 <user> 요소의 네임스페이스를 혼란스럽게 하지 않으면서도 원하는 만큼 필드를 확장할 수 있다. 해당 문서의 유효성을 검증할 수 있으며
XPath(//user/userdata/field[@name='runningpace')를 사용하여 특정 필드를 참조할 수도 있다.
필자는 이 기사에서 많은 것을 생각하도록 했다. 다섯 가지는 하지 말라는 것이었고 또 다른 다섯 가지는 하도록 권장하는 것이었다. 이러한 모든 것들이 모든 상황에 적용되는 것은 아니다. XML이 단지 일반적으로 사용되는 지속성 형식일 뿐이고 그 수명도 몇 밀리초에 불과할 때도 있다. 이러한 경우에는 사실상 아무도 관리를 하지 않는다. 그러나 XML을 파일 형식처럼 사용하는 경우에는 XML을 이와 같이 처리해야 하며 또한 여기서 살펴본 대부분의 우수 사례를 사용해야 한다.
교육
- 언어 변호사라면 W3C XML Specification을 살펴보고 싶을 것이다. 언어 변호사가 되어 대규모 전자 출판에 맞게 설계되었으며 웹과 그 밖의 분야에서
데이터 교환에 중요한 역할을 하는 단순하고 매우 유연한 텍스트 형식인 XML의 세부사항을 자세히 탐구해보자.
- Document Type Definition(DTD)(Wikipedia): SGML과 같은 유형의 마크업 언어(SGML, XML, HTML)에 적합한 문서 유형을 정의하는 마크업 선언 세트인 DTD에 관해 자세히 읽어보자.
- XML Schema(Wikipedia): 해당 유형의 문서의 구조와 내용을 제약하는 XML 문서 유형에 대한 간단한 설명을 읽어보자.
- W3C XSLT 스펙: XML을 다양한 형식으로 변환할 수 있는 유용한 방법을 자세히 배우자.
- W3C XPath 스펙: 가장 복잡한 XML 문서에서도 빠르고 쉽게 노드를 찾을 수 있는 매우 가치 있는 XML 도구를 탐구하자.
- Actionscript용 E4X 확장(ECMAScript): XML을 애플리케이션 논리에 직접 통합할 수 있는 매우 멋진 방법을 자세히 살펴보자. E4X 확장 덕택에
XML은 Actionscript에서 사실상의 개방형 스토리지 형식이 되었다. (Wikipedia)
- 필자의 더 많은 기사(Jack Herrington저, developerWorks, 2005년 3월 - 현재): Ajax, JSON, PHP, XML 및 다른 기술에 대한 기사를 읽어보자.
- developerWorks의 XML 영역: XML 영역에서 기술 향상에 도움이 되는 참고자료를 얻을 수 있다.
- My developerWorks: developerWorks와 관련된 경험을 개인화할 수 있다.
- IBM XML 인증: XML 및 관련 기술에 대한 IBM 인증 개발자가 되는 방법을 찾아볼 수 있다.
- XML 기술 자료: developerWorks XML 영역에서 다양한 기술 관련 기사와 팁, 튜토리얼, 표준 및 IBM Redbook을 볼 수 있다. 또한 더 많은 XML 팁을 읽어본다.
- developerWorks 기술 행사 및 웹 캐스트: 이러한 세션에 참가하여 최신 기술에 대한 정보를 얻을 수 있다.
- Twitter의 developerWorks 페이지: 오늘 가입하여 developerWorks 트윗을 팔로우하자.
- developerWorks podcasts: 소프트웨어 개발자의 흥미로운 인터뷰와 토론을 확인할 수 있다.
- developerWorks on-demand demos: 입문자를 위한 제품 설치 및 설정 과정에서 숙련된 개발자를 위한 고급 기능의 활용에 이르기까지 다양한 데모를 제공한다.
제품 및 기술 얻기
- XML development with Eclipse: Harness the power of XML with Eclipse(Pawel Leszek, developerWorks, 2003년 4월): 이 우수한 기사에서 Eclipse와 이 도구의 XML 편집 확장을 확인하자.
- IBM 제품 평가판: IBM SQA Sandbox의 온라인 시험판을 다운로드하거나 살펴보고 DB2®,
Lotus®, Rational®, Tivoli® 및 WebSphere®의 애플리케이션 개발 도구 및 미들웨어 제품을 사용해 볼 수 있다.
토론
- XML 영역 토론 포럼: 여러 XML 관련 토론에 참여해 볼 수 있다.
- developerWorks 포럼 & 블로그를 통해 developerWorks 커뮤니티에 참여하자.
Jack D. Herrington은 20년 경력의 소프트웨어 엔지니어이다. Code Generation in Action, Podcasting Hacks, PHP Hacks(출간 예정)의 저자이기도 하다. 30개 이상의 기술자료도 집필했다. (jack_d_herrington@codegeneration.net)