XML은 실제로 프로그래밍 언어로 쉽게 디코딩할 수 있고 표준 텍스트 편집기를 사용하여 사용자가 읽거나 쓸 수도 있는 방식으로 구조화된 데이터를 인코딩하는 데 필요한 인터넷 표준이다. 많은 애플리케이션(특히 최신 표준 준수 웹 브라우저)이 XML 데이터를 직접 처리할 수 있다.
텍스트 기반 표준으로서 XML은 클라이언트와 서버 시스템 간 데이터 교환에 적합하다. 많은 데이터(예: 파일 경로, 설명, 주소, 이름 등)가 이미 텍스트를 기반으로 하고 있으며 정수, 부동 소수점 숫자 및 날짜 등도 쉽게 문자열 표시로 변환하고 문자열 표시로부터 변환할 수 있다.
불행히도 XHTML 또는 XML 마크업과 같은 일부 데이터는 XML 문서에 포함하기가 쉽지 않다. 마크업을 XML 요소에 추가하는 한 가지 방법은 마크업 문자[미만(<), 초과(>) 및 앰퍼센드(&)]를 동등한 엔티티(각각 <, > 및 &)로 대체하는 것이다. 이 방법을 사용하면 데이터가 확장되고 사용자가 읽는 것이 매우 어려워질 뿐만 아니라 텍스트 편집기에서 수동으로 XML을 작성하는 경우에는 마크업을 변환해야 하는 번거로움도 있다.
더 나은 방법은 데이터를 직접 XML 문서에 추가하는 것이다. 여기서 XML의 CDATA 섹션이 제 역할을 한다.
XML 문서의 텍스트는 일반적으로 구문 분석된 문자 데이터이거나 PCDATA(Document Type Definition 용어)이다. XML의 특수 문자(&, < 및 >)는 PCDATA에서 인식되며 요소 이름과 엔티티를 구문 분석하는 데 사용된다. CDATA(문자 데이터) 섹션은 구문 분석기에 의해 데이터 블록으로 처리되기 때문에 데이터 스트림에 문자를 포함할 수 있다.
일부 HTML 또는 XML을 XML 문서에 추가하려고 한 적이 있는 경우에는 예제를 포함할 시기가 되자마자 이 문제가 발생했을 것이다. Listing 1에서는 일부 텍스트가 강조표시된 단순 단락 샘플을 보여 준다.
Listing 1. 샘플 요소의 일부 샘플 XHTML
<?xml version="1.0" encoding="UTF-8"?>
<sample>
<description>
Paragraphs can include emphasized text.
</description>
<example>
<p>The pug snoring on the couch next to me is
<em>extremely</em> cute.</p>
</example>
</sample>
|
마크업을 표시하려고 하는 경우에는 약간 어려워진다(Listing 2 참조).
Listing 2. 마크업이 표시되는 샘플 XHTML
<?xml version="1.0" encoding="UTF-8"?>
<sample>
<description>
Paragraphs can include emphasized text.
</description>
<example>
<p>The pug snoring on the couch next to me is
<em>extremely<em> cute.</p>
</example>
</sample>
|
CDATA 섹션에서 샘플 마크업을 랩핑하면 XML 구문 분석기가 <em> 요소가 포함된 <p> 요소로 해석하지 않고 있는 그대로 샘플 마크업을 작성할 수 있다. DTD 또는 XML 스키마에 대해 XML이 유효성 검증되고 있는 경우에는 이것이 필수이다(해당 요소가 DTD 또는 XSD에 실제로 존재하며 당시에 문서에 포함될 수 있는 경우는 제외). Listing 3을 참조한다.
Listing 3. CDATA를 사용하여 샘플 보호하기
<?xml version="1.0" encoding="UTF-8"?>
<sample>
<description>
Paragraphs can include emphasized text.
</description>
<example>
<![CDATA[<p>The pug snoring on the couch next to me is
<em>extremely</em> cute</p>]]>
</example>
</sample>
|
Listing 3의 간단한 예제에서 알 수 있듯이 CDATA 섹션은 특수 시퀀스 <![CDATA[로 시작하고 ]]> 시퀀스로 끝난다.
이러한 마크업 사이에 있는 항목은 모두 그대로 XML 구문 분석기를 통과한다. 일부 개발 플랫폼에는 CDATA 섹션의 컨텐츠를 표시하는 특별한 CDATA 오브젝트(예: XML DOm에 있는 CDATASection)가 있지만 다른 플랫폼에서는 해당 컨텐츠를 좀 더 일반적인 XML 텍스트 노드로 제공한다.
어느 경우든 CDATA 섹션의 컨텐츠는 수정 없이 사용할 수 있다.
XML은 일반적으로 공백에 매우 관대하지만 섹션의 끝 부분에 있는 ]]>는 공백이나 줄 바꿈을 포함할 수 없다.
임베디드 JavaScript가 있는 다수의 웹 페이지를 살펴본 경우에는 적용 중인 CDATA를 본 적이 있을 것이다. Listing 4와 같은 항목을 자주 보게 될 것이다.
Listing 4. XHTML의 <script> 요소에 있는 CDATA
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type"
content="application/xhtml+xml;charset=utf-8"/>
<title>CDATA Section in Action</title>
<script type="text/javascript">
// <![CDATA[
function nowWeAreSafe( x, y, z ) {
// Without the CDATA section, these would cause
// parsing errors:
if( x < y && y > z ) {
return y--;
}
return 0;
}
// ]]>
</script>
</head>
<body>
...
</body>
</html>
|
<script> 요소에 있는 JavaScript는 CDATA 섹션의 시작 부분이 포함된 주석으로 시작하고 CDATA 섹션을 마치는 주석으로 끝난다.
CDATA 섹션이 없으면 스크립트가 웹 브라우저의 XHTML 구문 분석기를 통해 실행된다는 것을 인식하기 전에는 이것이 HTML 및 JavaScript를 복잡하게 만드는 무의미한 방법처럼 보인다.
매우 운이 나쁜 경우가 아니면 이로 인해 문제가 발생하지는 않지만 혼동되고 디버깅하기 어려운 렌더링 오류의 원인이 되는 구문 분석기 오류를 확실히 유발할 수 있다. 왜냐고?
짐작했겠지만 <, > 및 & 문자는 요소나 엔티티(또는 부유 마크업 문자)로 플래그가 지정될 수 있다. 또한 이중 대시(--) 시퀀스는 XHTML 주석 블록의 예상치 않은 시작(또는 끝)으로 보여질 수 있다. 사실 이것 때문에 XML 주석 대신 CDATA 섹션에 임베디드 스크립트를 랩핑해야 한다. 주석은 지나치게 손상되기 쉽다.
CDATA는 인라인 <style> 요소에 표시되는 경우도 있지만 이것은 일반적인 경우가 아니다(Listing 5 참조).
Listing 5. CDATA는 <style> 요소에서 구문 분석 오류를 예방함
<style type="text/css">
/* <![CDATA[ */
body {
background-image:
url("marble.png?width=300&height=300")
}
/* ]]> */
</style>
|
클라이언트 웹 브라우저에서 CSS 구문 분석기에 혼동을 주지 않도록 CDATA 마커가 언어별 주석에서 어떻게 숨겨지는지 다시 한번 유의한다.
CDATA 섹션은 확실히 유용하지만 다른 모든 유용한 항목들과 마찬가지로 유의해야 할 몇 가지 제한사항이 있다.
브라우저는 HTML 또는 XHTML에서 신뢰성 있게 CDATA를 수행하지 않는다. CDATA 섹션은 XML 애플리케이션에 있기 때문에 XHTML의 모든 위치에서 허용되지만 실제로는 완전히 무시된다. 컨텐츠를 읽거나(CDATA 섹션이 일반적인 DOM에서 사라짐) 일부 부유 마크업 문자가 표시되는 텍스트로 컨텐츠를 렌더링한다.
효과를 확인하려면 샘플 단락을 보여 주는 페이지와 엔티티를 사용하여 마크업이 표시되는 샘플 단락을 살펴보고 CDATA를 사용하여 마크업이 표시되는 샘플 단락을 표시하려고 하는 시도를 살펴본다. XHTML 페이지 소스는 Listing 6에 있다.
Listing 6. XHTML로 CDATA 사용하기
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="application/xhtml+xml;charset=utf-8"/>
<title>CDATA Section in Action</title>
</head>
<body>
<h1>CDATA Section in Action</h1>
<p>
A sample paragraph:
</p>
<p>The pug snoring on the couch next to me is <em>extremely</em>
cute.</p>
<p>
Markup version:
</p>
<p id="no1">
<p>The pug snoring on the couch next to me is <em>extremely</em> cute.</p>
</p>
<p>
CDATA version:
</p>
<p id="no2">
Uh,
<![CDATA[<p>The pug snoring on the couch next to me is <em>extremely</em> cute.</p>]]>
where?
</p>
<p>
Wait, what?
</p>
</body>
</html>
|
그림 1과 같이 Firefox 3는 CDATA 섹션의 컨텐츠를 무시한다(그림 1의 텍스트 전용 버전 보기).
그림 1. Firefox는 CDATA 섹션을 무시함
Safari와 Chrome 같은 WebKit 기반 브라우저는 가짜 마크업 문자로 CDATA 섹션을 렌더링한다.(그림 2 참조). (그림 2의 텍스트 전용 버전 보기)
그림 2. Safari와 Chrome은 CDATA 섹션을 렌더링함
Internet Explorer®도 비슷한 가짜 마크업 문자로 CDATA 섹션을 렌더링한다(그림 3 참조). (그림 3의 텍스트 전용 버전 보기)
그림 3. Internet Explorer 8도 CDATA 섹션을 렌더링함
브라우저는 CDATA 섹션이 XHTML 문서에 포함되면 제대로 작동하지 않지만 Ajax를 통해 로드된 XML 문서에서는 해당 섹션을 제대로 처리해야 한다. 그렇지 않으면 브라우저의 XML 구문 분석기가 "비준수"로 간주되기 때문에 사용자들은 Ajax용으로 심각하게 손상된 것으로 표시하기 전에 무자비하게 모방한다.
CDATA 섹션에 모든 항목을 추가할 수 있지만 섹션 종료 마커의 시퀀스(]]>)는
특별하게 취급된다. 절대로 CDATA 섹션을 중첩할 수 없다. XML 구문 분석기가 이 시퀀스를 읽으면 CDATA 섹션이 끝난 것으로 처리되기 때문에 실제 섹션 끝 부분에 도달했을 때 구문 분석기 오류가 발생할 수 있다.
달리 말하면 XML(또는 XHTML) 구문 분석기는 섹션 종료 마커 <![CDATA[를 제외한 마크업 문자를 무시하기 때문에 CDATA 섹션에서 ]]>를 사용해도 인식할 수 없다(Listing 7 참조).
Listing 7. 올바르지 않은 XML이다. CDATA 섹션을 중첩시킬 수 없다
<?xml version="1.0" encoding="UTF-8"?>
<sample>
<description>
You can't nest CDATA sections.
</description>
<example>
<![CDATA[You want a <![CDATA[ ]]> inside your
example? No, this is wrong.]]>
</example>
</sample>
|
섹션 종료 마커를 CDATA 섹션에 추가해야 하는 경우 무엇을 할 수 있는가? CDATA 섹션을 두 개의 CDATA 섹션으로 나누어야 한다(Listing 8 참조).
Listing 8. CDATA 섹션에서 섹션 종료 시퀀스를 추가하는 올바른 방법
<?xml version="1.0" encoding="UTF-8"?>
<sample>
<description>
Split up the section end.
</description>
<example>
<![CDATA[You want a ]]]]><![CDATA[>
inside your example? Do it this way.]]>
</example>
</sample>
|
시퀀스의 최종 >가 대괄호와 떨어져 있도록 데이터에 있는 ]]>를 모두 ]]]]><![CDATA[>로 대체한다.
구문 분석기는 구체적으로 ]]>를 세 문자 시퀀스로 검색하며 이를 분할하면 시퀀스를 파괴하는 것이다.
그리고 ]]]]><![CDATA[>에는 마크업이 지나치게 많다.
다행히 이 상황은 그리 자주 발생하지 않는다.
CDATA 섹션의 컨텐츠는 그대로 구문 분석기를 통과하더라도 문서의 문자 인코딩에 지정된 대로 유효한 XML 데이터 문자여야 한다. UTF-8과 같은 방식을 사용하면 광범위한 문자를 데이터에 사용할 수 있지만 8비트 문자를 제대로 처리하지 못한다.
제어 문자(0x20 미만의 16진 값을 가진 문자, 공백 문자)는 구문 분석기를 중지하여 올바르지 않은 토큰 오류를 유발할 수 있다. 데이터를 가져와서 CDATA 섹션에 덤프했는데도 올바른 문서가 될 수는 없다.
CDATA 섹션이 포함된 XML에 많은 데이터를 추가할 때 유의해야 할 마지막 항목은 크기이다. 웹 서비스를 통해 XML 파일을 제공하는 경우 데이터가 3G 연결을 통해 유입될 때 클라이언트 애플리케이션이 사용자 인터페이스를 제한시간 초과하거나 차단하지 않고 잠재적으로 큰 규모의 데이터 전송을 처리할 수 있도록 한다.
그 반대도 적용된다. 서버가 XML 데이터를 전송하는 클라이언트로부터 큰 규모의 업스트림 전송을 승인할 수 있도록 한다. 웹 서버(특히 Windows® 플랫폼의 IIS)는 서비스 거부 공격을 예방하기 위해 매우 작은 업로드 제한을 두고 있는 경우가 종종 있다. 이와 같이 브라우저에서 많은 데이터 블록을 전송하면 오류가 발생하기 쉽다(예를 들어, 사용자가 전송이 손상되었다고 생각하여 전송을 취소하는 경우를 생각해 보자). 또한 서버와 클라이언트의 소중한 자원에 잠금을 설정하는 경향이 있다.
어떤 작업을 수행하는지에 따라, LAN 외부에서 애플리케이션이 작동한다고 가정하면 다수의 사용자가 모바일 플랫폼을 사용하고 있지만 아직도 전화 접속 연결을 사용하고 있는 사용자도 있다는 것에 유의해야 한다.
의도하지는 않았더라도 iPhone의 전화 접속 VPN 연결을 통해 사용을 시도하는 사용자가 있을 수 있으며 이들은 자신의 선택보다 애플리케이션의 속도에 불만을 나타낼 것이다.
XML 문서에 2진 데이터를 포함해야 하는 경우에는 XML 구문 분석기에 문제를 일으키지 않도록 해야 한다. 데이터가 텍스트인 경우 해당 데이터를 CDATA 섹션에 덤프하여 완료할 수 있지만 안전하고 복구 가능한 방식으로 2진 데이터를 인코딩해야 한다.
다행히 MIME 표준은 지원이 잘 되는 안전한 인코딩 스키마인 base64를 정의한다. base64 인코딩을 사용하면 2진 데이터가 원래 크기의 약 137%로 되기 때문에 XML 문서에 2진 데이터를 임베드하는 기능을 위해 추가적인 스토리지 공간(및 약간의 처리 속도)의 감소를 감내한다.
일반적으로는 Listing 9와 같이 XML에 인코딩 및 원래 파일 이름을 표시하려고 한다.
Listing 9. XML 문서에 있는 base64 인코딩된 파일의 한 가지 예제
<?xml version="1.0" encoding="UTF-8"?>
<sample>
<description>
An embedded image file.
</description>
<image name="stop.png" encoding="base64"
source="FamFamFam"
href="http://www.famfamfam.com/lab/icons/silk/">
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQ
CAYAAAAf8/9hAAAABGdBTUEAAK/INwWK
6QAAABl0RVh0U29mdHdhcmUAQWRvYmUg
SW1hZ2VSZWFkeXHJZTwAAAJOSURBVDjL
pZI9T1RBFIaf3buAoBgJ8rl6QVBJVNDC
ShMLOhBj6T+wNUaDjY0WmpBIgYpAjL/A
ShJ+gVYYYRPIony5IETkQxZ2770zc2fG
YpflQy2MJzk5J5M5z/vO5ESstfxPxA4e
rL4Zuh4pLnoaiUZdq7XAGKzRJVbIBZ3J
PLJaD9c/eCj/CFgZfNl5qK5q8EhTXdxx
LKgQjAFr0NK0ppOpt9n51D2gd2cmsvOE
lVcvOoprKvuPtriNzsY8rH+H0ECoQEg4
WklY1czP8akZby51p6G3b6QAWBl43llS
VTlUfuZE3NmYh9Vl0HkHSuVq4ENFNWFd
C+uJ5JI/9/V2Y//rkShA1HF6yk/VxJ0f
07CcgkCB7+fSC8Dzcy7mp4l9/khlUzwe
caI9hT+wRrsOISylcsphCFLl1RXIvBMp
YDZJrKYRjHELACNEgC/KCQQofWBQ5nuV
64UAP8AEfrDrQEiLlJD18+p7BguwfAoB
UmKEsLsAGZSiFWxtgWWP4gGAkuB5YDRW
ylKAKIDJZBa1H8Kx47C1Cdls7qLnQTZf
fQ+20lB7EiU1ent7sQBQ6+vdq2PJ5dC9
ABW1sJnOQbL5Qc/HpNOYehf/4lW+jY4v
h2tr3fsWafrWzRtlDW5f9aVzjUVj72Fm
CqzBypBQCKzbjLp8jZUPo7OZyYm7bYkv
w/sAAFMd7V3lp5sGqs+fjRcZhVYKY0xu
pwysfpogk0jcb5ucffbbKu9Esv1Kl1N2
+Ekk5rg2DIXRmog1Jdr3F/Tm5mO0edc6
MSP/CvjX+AV0DoH1Z+D54gAAAABJRU5E
rkJggg==
</image>
</sample>
|
시스템에서 생성된 XML 문서에서는 공백을 그대로 두고 줄 바꾸기 문자 없이 전체 base64 인코딩된 파일을 함께 실행할 수 있다.
XML의 2진 데이터를 처리하는 가장 좋은 방법은 전부를 회피하는 것이다. HTML에서 확인했듯이 표준화된 방식으로 외부 파일을 참조하는 것은 제대로 작동된다. 클라이언트 애플리케이션에서 외부 파일을 가져오는 방식이 있는 경우에는 매우 좋은 옵션이다. HTML의 경우 브라우저는 <img>와 같은 요소를 통해 포함된 데이터를 가져오기 위해 또다른 HTTP 요청을 작성한다.
XML에 직접 2진 데이터를 포함하지 않음으로써 잠재적으로 낭비되는 텍스트 인코딩을 예방하고 대부분의 사용자가 웹 브라우저에서 애용하는 이미지 캐싱과 같은 다른 개선사항을 구현할 수 있다.
XML의 CDATA 섹션(<![CDATA로 시작하고 ]]>로 끝남)을 사용하여 문서의 일부가 구문 분석기의 관리를 받지 않도록 할 수 있다.
내부의 데이터는 들어올 때와 정확하게 동일한 텍스트로 구문 분석기에서 나오지만 CDATA 섹션을 중지한 후 다시 시작하여 ]]> 시퀀스를 보호해야 한다.
XHTML 문서에서 CDATA 섹션을 활용할 수 있지만 XML은 브라우저와 일반적인 프로그래밍 플랫폼에서 제대로 지원된다. CDATA를 사용하여 XML 문서에 직접 마크업된 데이터를 임베드하면 데이터를 인코드하지 않아도 되지만 유의해서 클라이언트 및 서버 애플리케이션에 대한 잠재적인 대규모 데이터 전송의 효과를 고려해야 한다.
2진 데이터를 XML 문서에 저장해야 하는 경우에는 외부 파일을 참조하는 것이 더 나을 수 있지만 표준 MIME base64 인코딩과 같은 텍스트 인코딩을 사용할 수 있다.
교육
- Process XML in the browser using jQuery(Uche Ogbugi, developerWorks, 2009년 12월): jQuery를 사용하여 브라우저에서 직접 XML을 처리하는 방법에 대해 살펴보자.
- Combine social media APIs and XML-based data formats(J. Jeffrey Hanson, developerWorks, 2009년 12일): XML 파일에서의 데이터 인코딩에 대해 자세히 살펴보자.
- Aggregate RSS and Atom information using XQuery(Martin Brown, developerWorks, 2008년 2월): CDATA 섹션 처리를 포함하여 XQuery를 사용하여 RSS와 Atom 피드를 집계하는 방법을 살펴보자.
- PHP에서 풀(pull) 방식으로 XML 구문을 분석하는 방법 (한글)(Elliotte Rusty Harold, developerWorks, 2008년 1월): PHP의 풀(pull) 구문 분석기가 CDATA 섹션을 처리하는 방법을 살펴보자.
- Multipurpose Internet Mail Extensions 스펙: base64 인코딩의 표준(RFC 2045)을 포함하여 MIME 스펙에 있는 이메일 및 기타 텍스트 기반 미디어에 대한 멀티미디어 표준에 대해 자세히 살펴보자.
- XML 1.0 스펙(W3C Recommendation, 2008년 11월 26일): 이 기사에서 CDATA 섹션과 같은 XML 기능에 대한 세부사항을 살펴보자.
- The XML FAQ: XML 정보의 또다른 우수한 소스인 Peter Flynn이 편집한 XML FAQ를 살펴보자.
- W3schools.com의 XML DOM Tutorial: 브라우저에 사용할 수 있는 XML 기반 인터페이스와 이러한 인터페이스를 지원하는 브라우저에 대해 알아보자.
- Using XMLHttpRequest: Ajax 호출 결과의 처리에 대한 적절한 기사를 읽어 보자.
- XML Entity Definitions for Characters(W3C Working Draft, 2009년 11월 17일): 유니코드 문자에 지정된 몇 가지 이름 세트에 대해 살펴보자.
- XHTML™ 1.0: The Extensible HyperText Markup Language(World Wide Web Consortium Recommendation, 2000년 1월 26일): XML 1.0 애플리케이션으로 HTML 4를 다시 공식화하고 XHTML의 향후 확장성의 기반을 제공하는 XHTML 1.0에 대해 자세히 살펴보자.
- developerWorks의 XML 영역: XML 분야의 기술을 향상시키는 데 도움이 되는 참고자료를 얻을 수 있다.
- IBM XML 인증: XML 및 관련 기술에 대한 IBM 인증 개발자가 되는 방법을 찾아볼 수 있다.
- XML Technical library: developerWorks XML 영역에서 다양한 기술 관련 기사와 팁, 튜토리얼, 표준 및 IBM Redbook을 볼 수 있다.
- developerWorks 기술 행사 및 웹 캐스트: 이들 세션에 참가하여 최신 기술에 대한 정보를 얻을 수 있다.
- developerWorks
팟캐스트: 소프트웨어 개발자의 흥미로운 인터뷰와 토론을 확인할 수 있다.
제품 및 기술 얻기
- IBM 제품 평가판: IBM SQA Sandbox의 온라인 시험판을 다운로드하거나 살펴보고 DB2®,
Lotus®, Rational®, Tivoli® 및
WebSphere®.
토론
- XML 영역 토론 포럼: 여러 XML 관련 토론에 참여해 볼 수 있다.
- developerWorks
포럼 & 블로그: 이러한 블로그를 읽어보고 참여할 수 있다.