GnuSmalltalkUsersGuide:AdditionalChapter8 2

From 흡혈양파의 번역工房
Jump to navigation Jump to search
XML 빌드하기

XML 빌드하기

향후에 무언가가 XML 문서를 처리하지 않는다면 굳이 문서를 빌드해야 할 이유가 없다. 대부분의 XML 툴은 XMl 문서에 문서 루트가 있도록 요한다. 루트는 다른 모든 태그가 존재하는 내부의 태그, 바꿔 말하자면 다른 모든 노드들이 내려오는 단일 부모 노드이다. 필자의 경우 한 동료가 Sablot의 sabcmd를 이용해 내 서버로부터 XML을 HTML으로 변환하고자 했다. 그렇다면 루트가 있는 문서로 시작해보자:

replyDoc := XML Document new.
replyDoc addNode: (XML Element tag: 'response').


좀 더 복잡한 것을 시작하기 전에 우리의 새 XML 문서를 갖고 놀 수 있겠다. 누군가에게 XML 텍스트를 전송하거나 이를 파일로 작성하길 원한다고 가정하면 우선 이를 문자열로 캡처(capture)하길 원할 것이다. 설사 문자열로 먼저 캡처를 원하지 않는다 하더라도 이번 예제에서는 그렇게 할 것이다:

replyStream := String new writeStream.
replyDoc printOn: replyStream.


replyStream (replyStream contents) 내용을 살펴보았다면 아래가 보일 것이다:

<response/>


빈 태그의 모습이다.


이제 우리의 XML 문서에 텍스트를 추가해보자. 아래와 같은 모양이 되길 원한다고 치자:

<response>Hello, world!</response>


이를 빌드하려면 두 개의 노드가 새 XML 문서로 추가될 필요가 있다. 첫 번째 노드(또는 요소)는 response로 명명된다. 두 번째 노드는 첫 번째 노드에 텍스트를 추가한다:

replyDoc := XML Document new.
replyDoc addNode: (XML Element tag: response). "our root node"
replyDoc root addNode: (XML Text text: 'Hello, world!').


또 다른 작성 방법으로 추가하기 전에 전체 노드를 생성하는 방법이 있는데 필자 또한 이를 이용했다. 이는 할당자(assignment)의 모양을 줄여줄 뿐만 아니라 #addNode: 메시지를 요소로 cascading하기 위한 템플릿을 제시하는데, 중요한 XML을 빌드할 경우 아래를 많이 이용할 것이다:

replyDoc := XML Document new.
replyDoc addNode: (
    (XML Element tag: response)
        addNode: (XML Text text: 'Hello, world!')
).


앰퍼샌드(&)가 포함된 텍스트 노드를 실수로 추가하는 일이 절대로 없도록 보장하지 않는 이상 XML 파서를 지나치도록 벗어나야(escape) 할 것이다. 필자는 텍스트 노드를 추가할 때마다 벗어나는 방법을 이용했다. 이를 수월하게 만들기 위해 내 객체들의 추상적 슈퍼클래스에 (다시) 메서드를 생성했다:

asXMLElement: tag value: aValue
    | n |
    
    n := XML Element tag: tag.
    aValue isNil ifFalse: [
            n addNode: (XML Text
    text: (aValue displayString copyReplaceAll: '&' with: '&amp;'))].
    ^n

self asXMLElement: 'sometagname' value: anInstanceVariable 로의 호출이 필자의 코드에 지저분하게 포함되어 있다.


속성을 문서에 추가하는 작업은 다행히도 접근하는 작업보다 수월하다. 위의 문서로 속성을 추가하길 원한다면 하나의 문으로 가능하다:

replyDoc root addAttribute: (XML Attribute name: 'isExample' value: 'yes').


이제 우리 XML은 아래와 같은 모습일 것이다:

<response isExample="yes">Hello, world!</response>


Notes