 |
|
난이도 : 초급 Adriaan de Jonge, 소프트웨어 전문가, 프리랜서 S. E Slack, 저자 겸 비즈니스 변혁 커뮤니케이션 자문위원, Studio B
옮긴이: 장동수 dwkorea@kr.ibm.com
2008 년 11 월 25 일 XML은 구조적인 문서와 데이터를 교환하기 위한 통신 형식입니다. XML 형식을 충분한 계획이나 설계 없이 개발 중에 즉흥적으로 선택하는 경우가 많습니다. 올바른 XML 형식의 설계가 선행되어야, 통신에 참여하는 모든 이들의 요구를 만족시킬 수 있습니다. 그렇지 못하면, 오랫동안 힘들게 개정해 나가야 합니다. 이 글에서는 전체를 바꾸는 대신 새로운 확장을 조금 더해 새로운 요구사항에 기민하게 대응할 수 있는 형식을 설계하는 방법을 알아보겠습니다.
지난 10여년 동안, XML은 조직 내부와 조직 간에 데이터를 저장하고 교환하기 위해 널리 사용되는 표준이 되었다. XML 그 자체는 추상적인 것에 불과하므로, 조직이나 조직에 속한 그룹에서 설계한 XML 형식에 의해 성패가 결정된다. 다른 모든 소프트웨어 제품들과 마찬가지로, XML 형식은 비지니스 요구의 변화에 따라 유지보수가 필요하다. 그리나 일반적으로 필요한 변화가 아니다. XML 형식은 동시에 여러 조직에 의해 경쟁이나 시장 상황에 따라 자주 갱신되어야 한다.
 |
공통으로 사용된 약어
-
NXD: Native XML database
-
XSD: XML Schema Definition
-
XSLT: XML Stylesheet Language Transformation
-
W3C: World Wide Web Consortium
-
XML: Extensible Markup Language
|
|
한 개의 XML 스키마를 유지보수하는 일은 상대적으로 간단하다. 그러나 수백 개 조직에 영향을 미치는 변화는 엄청난 충격이 될 수 있다. 사소한 XML 스키마의 변화를 알리기 위해 많은 시간과 막대한 비용을 들일 수도 있다. 이 기사에서는 두 가지를 다룰 것이다.
- 이 충격을 관리하는 방법
- 이 충격을 가능한 한 최소화하는 방법
자동차(car), 타이어(tire), 앞유리(windscreen) 관련 업체나 리셀러를 포함하는 매우 단순화된 예제를 사용할 것이다. 완전히 현실적이지는 않지만, XML 형식을 유지보수성을 향상시키는 방법을 설명하기에는 충분할 것이다.
단순하지만 문제가 있는 방법
 |
XML 스키마 소개
XML 스키마는 XML 형식을 기술하는 공식적인 방법이다. XML 도구들은 XML 스키마를 사용하여 XML 문서를 검증한다. 즉, XML 문서가 XML 스키마에서 지정한 형식을 따르는지 여부를 확인할 수 있다. XML 스키마의 전신이 DTD(Document Type Definition)인데, 아직도 HTML을 기술하는 데 사용된다. XML 스키마의 특징 중 한 가지는 그 자체가 XML로 표현된다는 점이다. 사실, XML 스키마로 XML 스키마 형식을 기술할 수도 있다. XML 형식을 표현하기 위해 개발된 언어로는 XML Schema(W3C)와 RELAX NG 등이 있다. XML 스키마는 XML Schema Definition이라고도 한다.
XML 문서가 연관된 스키마의 요구조건을 만족할 때만 유효한 것으로 간주된다.
|
|
먼저, 미쉐린 타이어를 장착한 볼보(Volvo) C30을 예제로 사용하여, 타이어에 대한 정보를 공유하기 위한 XML 파일을 만들어보자(Listing 1).
Listing 1. 타이어에 대한 정보를 공유하기 위한 간단한 XML 예제 파일
<car>
<brand>Volvo</brand>
<type>C30</type>
<kind>Small family car</kind>
<tires>
<tire>
<brand>Michelin</brand>
<type>Winter</type>
<count>4</count>
</tire>
<tire>
<brand>Michelin</brand>
<type>Spare</type>
<count>1</count>
</tire>
</tires>
<windscreen count="1">
<brand>Car glass</brand>
</windscreen>
</car>
|
위의 XML 파일은 꽤 단순하다. 언뜻 보기에는 아무런 문제가 없다. 그러나 더 자세히 살펴보자. 실질적인 문제는 XML 스키마에 있다. 결론부터 얘기하면 너무 크고 똘똘 뭉쳐있다. 이 XML 형식에는 요소가 많지 않다는 점을 고려할 때 현실적인 예에서는 Listing 2가 얼마나 커질지 상상해 보라.
Listing 2. 간단한 XML 형식을 기술하는 XML 스키마
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="car">
<xs:complexType>
<xs:complexContent>
<xs:extension base="brand">
<xs:sequence>
<xs:element ref="type"/>
<xs:element ref="kind"/>
<xs:element ref="tires"/>
<xs:element ref="windscreen"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="kind" type="xs:string"/>
<xs:element name="tires">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" ref="tire"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="tire">
<xs:complexType>
<xs:complexContent>
<xs:extension base="brand">
<xs:sequence>
<xs:element ref="type"/>
<xs:element ref="count"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:element name="count" type="xs:integer"/>
<xs:element name="windscreen">
<xs:complexType>
<xs:complexContent>
<xs:extension base="brand">
<xs:attribute name="count" use="required" type="xs:integer"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:element>
<xs:complexType name="brand">
<xs:sequence>
<xs:element ref="brand"/>
</xs:sequence>
</xs:complexType>
<xs:element name="brand" type="xs:string"/>
<xs:element name="type" type="xs:NCName"/>
</xs:schema>
|
"뭐 어때서? 아무도 XSD 파일을 보지 않는다구!"라고 하기 전에, 비지니스를 진행하는 동안 필요한 변화에 대해 다시 생각해 보자. 타이어 크기를 표시하기 위해 타이어 XML을 변경해야 한다면 어떻게 될까?
[...]
<tire>
<brand>Michelin</brand>
<type>Winter</type>
<count>4</count>
<size>20"</size>
</tire>
[...]
|
이 XML 형식을 사용하면, 타이어 형식에 어떤 변화라도 있으면 앞유리 회사가 새 XSD를 받아야 한다. 거기에 덧붙여, XSD를 처리할 수 있도록 소프트웨어를 변경해야 할지도 모른다. 이건 문제가 있다. 앞유리 회사는 불필요한 작업을 하느라 비용을 지출해야 한다. 소프트웨어를 어떻게 만들었냐에 따라 타이어 회사도 새 XSD를 받아 그것을 처리할 수 있도록 소프트웨어를 개정해야 한다. XSD를 읽는 사람은 별로 없겠지만, 확실히 많은 사람에게 큰 골칫거리가 될 수 있다.
신속한 해결책: 모듈
괴물 같은 XSD 파일을 피하는 해결책은 타이어와 앞유리에 고유한 네임스페이스(namespace)를 부여하고 별도의 XSD 파일을 사용하는 것이다(Listing 3).s
Listing 3. 네임스페이스를 사용하여 수정된 예제 XML 파일
[...]
<tr:tires>
<tr:tire count="4">
<tr:brand>Michelin</tr:brand>
<tr:type>Winter</tr:type>
</tr:tire>
<tr:tire count="1">
<tr:brand>Michelin</tr:brand>
<tr:type>Spare</tr:type>
</tr:tire>
</tr:tires>
<wnd:windscreen count="1">
<wnd:brand>Car glass</wnd:brand>
</wnd:windscreen>
[...]
|
여기까지만 하고 자동차 XML 예제의 나머지 부분을 손대지 않고 남겨 두면, XSD 파일은 더 짧아지고 더 다루기 쉬워질 것이다. 관련된 정보는 대부분 XSD 파일의 맨 위에서 import되는 다른 XSD로 옮겨진다. XSD 파일은 Listing 4처럼 모듈화되었다.
Listing 4. 분리된 타이어와 앞유리 XSD를 사용하여 수정된 자동차 XML 스키마
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
targetNamespace="http://car.org/car"
xmlns:tr="http://car.org/tire"
xmlns:wnd="http://car.org/windscreen"
xmlns:car="http://car.org/car">
<xs:import namespace="http://car.org/tire" schemaLocation="tr.xsd"/>
<xs:import namespace="http://car.org/windscreen" schemaLocation="wnd.xsd"/>
<xs:element name="car">
<xs:complexType>
<xs:sequence>
<xs:element ref="car:brand"/>
<xs:element ref="car:type"/>
<xs:element ref="car:kind"/>
<xs:element ref="tr:tires"/>
<xs:element ref="wnd:windscreen"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="brand" type="xs:NCName"/>
<xs:element name="type" type="xs:NCName"/>
<xs:element name="kind" type="xs:string"/>
</xs:schema>
|
이제 이 파일은 XSD의 한 모듈일 뿐이다. 여기에서 보이는 것처럼 XSD 파일이 실제로 줄어들지는 않았지만, 더 중요한 점은 XSD가 모듈화되어 더 다루기 쉬워졌다는 것이다. 결과적으로 타이어 형식이 수정되더라도, 아무 상관없는 앞유리 회사들을 귀찮게 하지 않고, 모든 타이어 화사에게 배포할 수 있게 되었다.
모듈의 긍정적인 부수 효과
모듈화의 효과는 유지보수해야 할 것들이 분산되는 문제를 해결할 뿐 아니라, 단일 요소의 재사용성을 높인다. 예를 들어, 타이어 회사가 자동차용 타이어뿐 아니라 자전거용 타이어도 생산한다고 가정해 보자. 타이어 회사는 자전거 타이어에도 같은 타이어 XSD를 사용하려고 한다. 그러나 자전거 회사는 이 회사의 타이어를 구매하더라도 자동차에 대한 XML 스키마는 원치 않을 것이다. 예를 들어, 일반적인 자전거는 앞유리가 필요 없다. 자전거 회사는 타이어 XSD를 사용하는(import) 고유한 자전거 XSD가 필요하다.
이 시나리오에 따르면 Listing 5와 비슷한 XML이 나온다.
Listing 5. 타이어 XML 형식을 재사용하여 자전거를 기술하는 예제 XML 파일
<bicycle>
[...]
<tr:tire count="2">
<tr:brand>Gazelle</tr:brand>
<tr:type>Race</tr:type>
<tr:size>25"</tr:size>
</tr:tire>
[...]
</bicycle>
|
이것은 자동차 XSD와 비슷하게 타이어를 사용했지만, 자전거에 특화되어 있다. 이제 다음 예제를 위해 자동차로 돌아가자.
현실적인 모듈 관리
마침내 자동차 XSD는 앞유리 XSD와 타이어 XSD뿐 아니라 모터 XSD, 스티어링 휠 XSD, 좌석 XSD, 페인트 XSD 등을 사용하게 되었다. 관리하기 어려워졌다. 이 문제에 대한 해결책은 자동차의 모든 부품을 import하는 parts.xsd라는 별도의 XSD를 만들고, 그것을 include하는 것이다. 이 방법으로, import 목록이 바뀌더라도 이들 간의 의존성을 관리하는 parts.xsd 파일만 변경하면 된다. 변경된 자동차 XSD가 Listing 6에 나와 있다.
Listing 6. import 목록을 한 개의 include로 대체한 자동차 XML 스키마
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
targetNamespace="http://car.org/car"
xmlns:tr="http://car.org/tire"
xmlns:wnd="http://car.org/windscreen"
xmlns:car="http://car.org/car">
<xs:include schemaLocation="parts.xsd"/>
<xs:element name="car">
<xs:complexType>
<xs:sequence>
<xs:element ref="car:brand"/>
<xs:element ref="car:type"/>
<xs:element ref="car:kind"/>
<xs:element ref="tr:tires"/>
<xs:element ref="wnd:windscreen"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="brand" type="xs:NCName"/>
<xs:element name="type" type="xs:NCName"/>
<xs:element name="kind" type="xs:string"/>
</xs:schema>
|
반면 parts.xsd 파일은 Listing 7과 같다.
Listing 7. parts.xsd: 포함될 import 목록
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
targetNamespace="http://car.org/car"
xmlns:tr="http://car.org/tire"
xmlns:wnd="http://car.org/windscreen"
xmlns:car="http://car.org/car">
<xs:import namespace="http://car.org/tire" schemaLocation="tr.xsd"/>
<xs:import namespace="http://car.org/windscreen" schemaLocation="wnd.xsd"/>
</xs:schema>
|
parts.xsd를 사용하는 실질적인 이점은, 모든 XSD 파일이 이 부품들을 참조할 필요가 있더라도 XSD import 목록이 모든 XSD 파일로 복사될 필요가 없다는 것이다. 대신 한 개의 include면 충분하다.
현실 세계의 위험 요소
현실 세계의 문제에서 요소의 부품 개수가 늘어감에 따라, 더 주의깊게 타입을 정의해야 한다. 예를 들어, 흔히들 XML 형식에 Listing 8처럼 약간 위험할 수 있는 네임스페이스 없는 속성을 사용한다.
Listing 8. 네임스페이스 없는 count 속성을 사용하는 XML 예제
<tr:tires>
<tr:tire count="4">
<tr:brand>Michelin</tr:brand>
<tr:type>Winter</tr:type>
</tr:tire>
<tr:tire count="1">
<tr:brand>Michelin</tr:brand>
<tr:type>Spare</tr:type>
</tr:tire>
</tr:tires>
<wnd:windscreen count="1">
<wnd:brand>Car glass</wnd:brand>
</wnd:windscreen>
|
네임스페이스 없는 속성을 기준으로 요소를 선택하면, 결과를 예측하기 어렵다. 예를 들어, 다음과 같은 XPath 쿼리를 사용하여 count 속성의 값이 1 인 모든 요소를 선택하면, 결과에 포함된 네임스페이스를 예측할 수 없다.
이 예는 간단하기 때문에 네임스페이스를 예측할 수도 있다. 그러나 핵심은 이런 경우가 빠르게 증가할 수 있다는 점이다. 해결책은 각 속성에 네임스페이스를 사용하는 것이다. Listing 9에서 미묘한 차이를 볼 수 있다.
Listing 9. 네임스페이스를 가진 count 속성을 사용한 XML 예제
[...]
<tr:tires>
<tr:tire tr:count="4">
<tr:brand>Michelin</tr:brand>
<tr:type>Winter</tr:type>
</tr:tire>
<tr:tire tr:count="1">
<tr:brand>Michelin</tr:brand>
<tr:type>Spare</tr:type>
</tr:tire>
</tr:tires>
<wnd:windscreen wnd:count="1">
<wnd:brand>Car glass</wnd:brand>
</wnd:windscreen>
[...]
|
다행히도 Listing 10에서 볼 수 있는 것처럼 XML 스키마의 차이도 미묘하다.
Listing 10. 네임스페이스를 가진 count 속성을 위한 타이어 XML 스키마
[...]
<xs:element name="tire">
<xs:complexType>
<xs:sequence>
<xs:element ref="tr:brand"/>
<xs:element ref="tr:type"/>
</xs:sequence>
<xs:attribute name="count" use="required" form="qualified" type="xs:integer"/>
</xs:complexType>
</xs:element>
[...]
|
극적인 효과는 없지만 주목할 만하다. 가능한 한 충돌 가능성을 방지하는 것은 좋은 습관이다.
더 일반적인 형식 설계하기
스토리지 백엔드로 관계형 데이터베이스를 사용할 때, 데이터베이스 테이블이나 필드를 1:1로 XML 형식으로 변환하는 경향이 있다. 그러나 이것은 모델링 자유도를 제한할 뿐 아니라 데이터베이스를 사용하지도 않는 다른 부분까지 데이터베이스 제약의 영향을 받게 만든다. Listing 1의 XML은 관계형 데이터베이스를 1:1 변환한 좋은 예다.
그러나 다르게 모델링할 수도 있다. 예컨데, 자동으로 모든 부품을 그린 자동차의 후방 레이아웃을 보고 싶다고 하자. 이것은 Listing 11의 XML 예제로 설명할 수 있는데, XSLT를 사용하면 SVG(Scalable Vector Graphics)로 변환할 수 있다. 언뜻 엄청나게 어려울 것 같지만 그렇진 않다. XML 파일을 먼저 만들어 보자.
Listing 11. 다른 구조의 XML 예제
<car>
<brand>Volvo</brand>
<type>C30</type>
<kind>Small family car</kind>
<tr:tire tr:count="2">
<tr:brand>Michelin</tr:brand>
<tr:type>Winter</tr:type>
</tr:tire>
<wnd:windscreen wnd:count="1">
<wnd:brand>Car glass</wnd:brand>
</wnd:windscreen>
<tr:tire tr:count="2">
<tr:brand>Michelin</tr:brand>
<tr:type>Winter</tr:type>
</tr:tire>
<tr:tire tr:count="1">
<tr:brand>Michelin</tr:brand>
<tr:type>Spare</tr:type>
</tr:tire>
</car>
|
이 XML 문서를 위한 자동차 XSD는 Listing 12에 나와 있다(car 요소의 complexType에 특히 주목하라).
Listing 12. 다른 구조를 기술하는 자동차 XML 스키마
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
targetNamespace="http://car.org/car"
xmlns:tr="http://car.org/tire"
xmlns:wnd="http://car.org/windscreen"
xmlns:car="http://car.org/car">
<xs:import namespace="http://car.org/tire" schemaLocation="tr.xsd"/>
<xs:import namespace="http://car.org/windscreen" schemaLocation="wnd.xsd"/>
<xs:element name="car">
<xs:complexType>
<xs:sequence>
<xs:element ref="car:brand"/>
<xs:element ref="car:type"/>
<xs:element ref="car:kind"/>
<xs:choice maxOccurs="unbounded">
<xs:element ref="tr:tire"/>
<xs:element ref="wnd:windscreen"/>
</xs:choice>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="brand" type="xs:NCName"/>
<xs:element name="type" type="xs:NCName"/>
<xs:element name="kind" type="xs:string"/>
</xs:schema>
|
이 파일을 XML 데이터베이스에 저장했다가 나중에 완전히 똑같은 XML 문서를 만들어 내는 것은 좀 더 복잡하다. 이럴 때는 NXD를 사용하면 편리하다. Exist DB는 간단한 오픈 소스 NXD다. IBM DB2 Express-C는 관계형 데이터베이스와 XML 데이터베이스의 통합된 해결책을 제공하는 무료로 사용할 수 있는 대안이다. IBM DB2 Express-C를 사용하면 데이터베이스에 SQL이나 XQuery 같은 순수 XML 기술을 사용하여 데이터베이스에 접근할 수 있다.
XML 스키마의 버전 관리와 문서화
대부분의 경우에, 여러 회사가 동일한 XML 스키마의 여러 버전을 동시에 사용하더라도, 지금 사용하는 버전과 그 버전에서 어떤 요소가 바뀌었는지 알고 있다면 문제가 없다. 이를 위해 XSD의 어노테이션(annotation) 요소를 사용하여 버전과 요소 정보를 기술하는 것은 좋은 습관이다. 어노테이션은 documentation과 appinfo 두 개의 요소를 포함할 수 있다.
documentation 요소는 그 이름에서 알 수 있는 그대로다. 더 흥미로운 것은 어떠한 것이라도 포함할 수 있는 appinfo 요소다. 예를 들어, Listing 13의 XSD는 버전을 포함하는 사용자 정의 요소인 version을 정의한다.
Listing 13. 사용자 정의 어노테이션을 갖고 있는 예제 XML 스키마
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
targetNamespace="http://car.org/tire"
xmlns:tr="http://car.org/tire"
xmlns:custom="http://car.org/custom">
<xs:element name="tires">
<xs:annotation>
<xs:appinfo>
<custom:version>0.91</custom:version>
</xs:appinfo>
<xs:documentation>
Describes a set of tires.
</xs:documentation>
</xs:annotation>
<xs:complexType>
|
비록 XSD 해석기는 사용자 정의 요소인 version에 대해 별다른 처리를 하지 않지만, 이러한 사용자 정의 요소는 큰 조직에서 XSD를 관리하는 데 큰 도움이 된다. 무엇보다도, XML 파일과 XML 스키마를 컴퓨터뿐만 아니라 사람이 보기에도 좋게 만들어 주고, XSD에 이러한 정보를 추가하는 것은 좋은 습관이다.
확장(extension) 소개
언급할 만한 XML 스키마의 마지막 기능은 extension 요소다. 이전 절에서 XSD의 appinfo 요소의 확장성을 보았다. 기본적으로 이 요소는 어떤 내용이라도 포함할 수 있다. extension 요소를 추가하는 것은 타입을 확장하는 더 제한적인 방법이다. Listing 14 의 XSD 파일은 basicTire 타입이 size 요소를 갖도록 확장하는 방법을 보여준다.
Listing 14. size 요소의 확장이 있는 타이어 XML 스키마
<xs:element name="tire" type="tr:sizedTire"/>
<xs:complexType name="basicTire">
<xs:sequence>
<xs:element ref="tr:brand"/>
<xs:element ref="tr:type"/>
</xs:sequence>
<xs:attribute name="count" use="required" form="qualified" type="xs:integer"/>
</xs:complexType>
<xs:complexType name="sizedTire">
<xs:complexContent>
<xs:extension base="tr:basicTire">
<xs:sequence>
<xs:element ref="tr:size"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
|
XML 스키마를 사용하면 명시적으로 basicType의 확장을 금지할 수 있다. XSD 스펙에 대해 더 자세한 내용은 참고자료를 참고하라. 분량 때문에 이 글에서는 다루지 못했던 XML 스키마의 흥미로운 기능을 많이 찾을 수 있을 것이다.
요약
대규모 사업과 주변 환경에서도 XML 형식이 유지보수하기 쉽도록 유지하려면, XML 스키마를 자동으로 생성되는 기술이라고 간주하면 안 된다. XML 스키마의 유지보수성을 향상시키기 위한 방법이 많다. 또한 XML 형식을 Schematron이나 RELAX NG 같은 다른 언어로 기술할 수도 있다. 무엇을 사용하든 간에, 올바른 XML 형식을 위한 설계가 선행되어야 참여하는 모두의 요구를 만족시킬 수 있다.
참고자료 교육
제품 및 기술 얻기
-
Exist DB: 오픈 소스 데이터베이스 관리 시스템을 다운로드하고 시험해보자. Exist DB는 XML 기술로 구축되었으며, XML 데이터 모델에 따라 XML 데이터를 저장하며, 효율적인 색인 기반 XQuery 처리 기능을 갖고 있다.
-
DB2 Express-C 9.5: 신뢰성, 융통성, 그리고 관계형 및 XML 데이터 서버가 제공하는 기능들을 시험해보자.
-
제품 평가를 위한 IBM의 시험판 소프트웨어: DB2®, Lotus®, Rational®, Tivoli®, WebSphere®의 애플리케이션 개발 도구와 미들웨어 제품을 포함하여, developerWorks에서 바로 받을 수 있는 시험판 소프트웨어들을 사용하여 차기 프로젝트를 구축하자.
토론
필자소개  | 
|  | Adriaan de Jonge는 현재 네덜란드 정부에서 여러 개의 프로젝트에서 여러 역할을 맡아 일하는 소프트웨어 전문가다. Adriaan 은 IBM developerWorks와 아마존에 XML 관련 기사들을 기고해 왔다. |
 | 
|  | S.E. Slack은 열 권이 넘는 기술 관련 책을 쓴 작가로 현재 콜로라도에서 가족과 함께 산다. 최신 저서로는 Windows Vista: Home Entertainment with Windows Media Center and Xbox 360(Microsoft Press, 2007)이다. 차기작은 PowerPoint 2007 Graphics and Animations Made Easy로 McGraw-Hill에서 출판할 예정이다. |
기사에 대한 평가
 |
| 이 문서 북마킹 하기
|
|