달력

4

« 2024/4 »

  • 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
2007. 2. 15. 19:13

06. XML 문서에 대한 유효성 검증 그거/Tech2007. 2. 15. 19:13

# 유효성 검증(validation)
  미리 정의된 문서의 구조와 XML 문서를 비교하는 작업

1. 기본 DOCTYPE
  DOCTYPE은 XML 문서에 포함되어야 하는 element나 attribute 또는 기타 객체 등을 명시하며, 문서의 상단부에 위치하는 선언부.

  <!DOCTYPE votes [ <!-- definition for element, attribute --> ]>

2. definition for element
  content model : element가 포함하는 요소들고 이 요소들의 정렬 순서, 발생 빈드 등에 대한 정보를 표현
  <!DOCTYPE votes [
   <!ELEMENT votes (voter*)>                votes element는 하나 이상의 voter element를 갖는다.
 <!ELEMENT voter (vote, comments)>        voter element는 vote element와 comments element를 갖는다.
 <!ELEMENT vote (#PCDATA)>                vote element는 일반적인 text나 parsing된 문자 데이터를 포함한다.
 <!ELEMENT comments (#PCDATA)>            comments element는 일반적인 text나 parsing된 문자 데이터를 포함한다.
  ]>

3. definition for attributes
  <!DOCTYPE votes [
     ...
  <!ATTLIST voter personid CDATA #REQUIRED
                  status CDATA "symbiont">
  <!ATTLIST votes totalVotes CDATA #REQUIRED>
  ]>

4. 외부 DTD
  XML 문서와는 별도로 분리된 파일에 문서의 구조 정보들을 포함
  SYSTEM 또는 PUBLIC 식별자에 의해 접근 가능
  <!DOCTYPE votes PUBLIC "-//Vanguard Resort IT//DTD Voting System 2.0//EN"        PUBLIC으로 접근 가능
                         "votes.dtd">                                              SYSTEM으로 접근 가능

# 문서의 유효성 검증

1. SAX 파서의 지원 기능
  SAX의 지원 기능 중 사용 빈도수가 많은 지원 기능
    http://xml.org/sax/features/validation
    http://xml.org/sax/features/namespace (required)
    http://xml.org/sax/features/namespace-prefixes (required)
    http://xml.org/sax/features/external-general-entities
    http://xml.org/sax/features/external-parameter-entities

2. SAX 파서에서의 유효성 검증의 실행

  XMLReader reader = XMLReaderFactory.createXMLReader();
  String featuredId = "http://xml.org/sax/features/validation";
  reader.setFeature(featureId, true); // 유효성 검사 지원 기능을 true로 설정

3. DOM 파서와 유효성 검증
 
  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  dbf.setValidating(true);

  이 factory class가 생성하는 모든 파서 객체들은 유효성 검증 property가 true로 설정된다.

4. DOM 파서에 SAX 오류 핸들러 설정

  DocumentBuilder db = dbf.newDocumentBuilder();
  db.setErrorHandler(new ErrorProcessor());


# XML Schema 이용시의 유효성 검증
  XML Schema를 사용하면 DTD에 비해 좀더 쉽고, 유연하며, 강력한 방법으로 유효성을 검증할 수 있다.

1. XML schema의 개요
  XML을 이용해서 XML 문서의 구조를 기술하는 방법을 제공

  XML schema의 예
  <?xml version="1.0"?>
  <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">

    <xsd:element name="votes" type="voteType"/>

   <xsd:complexType name="voteType">
     <xsd:sequence>
    <xsd:element name="voter" type="voterType" minOccurs="0" maxOccurs="unbounded"/>
  </xsd:sequence>
        </xsd:attribute name="totalVotes" type="xsd:integer"/>
   </xsd:compexType>

   <xsd:complexType name="voterType">
     <xsd:sequence>
    <xsd:element name="vote" type+"xsd:string"/>
    <xsd:element name="comments" type+"xsd:string"/>
     </xsd:sequence>
  <xsd:attribute name="personid" type="xsd:string"/>
  <xsd:attribute name="status" type="xsd:string"/>
   </xsd:complexType>
  </xsd:schema>

2. XML schema 문서의 명시
  namespace 선언을 위한 attribute를 사용하여 XML schema 문서를 명시한다.

  <votes totalVotes="5" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                              xsi:noNamespaceSchemaLocation="votes.xsd">

3. XML Schema에 대한 유효성 검증의 설정
 
  DocumentBuilderFactory dbf = DocumentBuilderFactory.newIntance();
  dbf.setValidating(true);
  dbf.setNamespaceAware(true);
  try {
   dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
                  "http://www.w3.org/2001/XMLSchema");
  } catch(IllegalArgumentException e) {
  }


# 오류의 처리

1. 오류와 SAX
  어차피 DOM 파서는 SAX와 관련된 예외 사항을 발생하기 때문에 SAX 관점에서 오류 처리를 한다.
  ErrorHandler를 상속받아 "error, fatalError, warning" method를 override하여 사용한다.

2. 오류의 처리

  try {
    ...
  } catch(Exception e) {
    SAXParseException spe = (SAXParseException)e;

    System.out.println("Problem parsing the file :  + spe.getMessage());
    System.out.println();
    System.out.println("File :  + spe.getSystemId());
    System.out.println("Line number :  + spe.getLineNumber());
    System.out.println("Column number :  + spe.getColumnNumber());
    System.out.println();
  }

3. 문서의 수정
  유효성 검증이 Document 객체에 대한 어떠한 영향력도 갖지 못한다.
  비록 문서가 유효성이 검증되었다 하더라도 Document 객체에 Schema에 위배되는 잘못된 정보를 추가할 수 있다.

  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  dbf.setValidating(true);
  dbf.setNamespaceAware(true);
  try {
   dbf.setAttribute("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
                  "http://www.w3.org/2001/XMLSchema");
  } catch(IllegalArgumentException e) {
    ...
  }
  DocumentBuilder db = dbf.newDocumentBuilder();
  db.setErrorHandler(new ErrorProcessor());

  Document doc = db.parse(new File("votes.xml"));

  Element root = doc.getDocumentElement();
  root.appendChild(doc.createTextNode("this node doesn't belong here.")); // Schema 정의에 없는 node를 추가
  System.out.println(root.getLastChild());

  위에서 추가한 text node는 Schema 정의에 존재하지 않는 정보임에도 불구하고, 이 application은 아무런 문제없이 계속 진행할 것이다.
  왜냐하면 이 application의 실행중에는 Document 객체에 대한 유효성을 검증할 방법이 없기 때문이다.


 

'그거 > Tech' 카테고리의 다른 글

08.XML Schema  (0) 2007.02.16
07.DTD(Document Type Definition)  (0) 2007.02.15
05. XML 스트림 (SAX)  (0) 2007.02.14
04. DOM의 활용(고급편)  (0) 2007.02.14
03. XML 문서의 처리 - DOM  (0) 2007.02.14
:
Posted by 뽀기
2007. 2. 14. 17:49

05. XML 스트림 (SAX) 그거/Tech2007. 2. 14. 17:49

- SAX 란?
  . DOM에서 처리하기 어려운 연산을 지원하기 위한 목적으로 XML-DEV 메일링 리스트의 구성원들이 만든 XML 처리를 위한 API
  . SAX는 XML 파일을 정보를 전달하는 이벤트들의 스트림으로 다룬다.
  . 스트림의 순서에 따라 이벤트를 검사하여 순차적으로 처리.

  <votes totalVotes="5">
 <voter personid="1" status="primary">
  <vote>Sparkel</vote>
  <comments>It's about time we had this vote!</comments>
 </voter>
  </votes>

  DOM parser의 관점
    . votes element는 2개의 text element(줄바뀜)와 하나의 element(voter)
   <votes>#text
     <voter>..
  </voter>#text
   </votes>
 . voter element는 3개의 text element(줄바뀜)와 2개의 element(vote, comments)
  <voter>#text
    <vote>Sparkel</vote>#text
    <comments>It's about time we had this vote!</comments>#text
  </voter>

  SAX parser의 관점
    elemnt(votes) 시작
 #text 무시
 elemtn(voter) 시작
 #text 무시
 elemtn(vote) 시작
 문자(Sparkle)
 element(vote) 종료
 #text 무시
 element(comments) 시작
 문자(It's a bout time we had this vote!)
 element(comments) 종료
 #text 무시
 element(voter) 종료
 #text 무시
 element(votes) 종료

  SAX vs DOM
    다루려는 XML 문서의 유형에 따라 적용.
 SAX
  읽기 전용의 method를 제공하기 때문에 정보를 읽을 수 있으나 소스 문서에는 아무런 변화를 줄 수 없다.
  단방향 method를 제공하기 때문에 한 번 읽고 처리된 element에 재접근하려면 문서를 다시 파싱해야 한다.
  시간 순서에 따라 처리하기 때문에 사용이 확실치 않은 정보들로 메모리를 낭비할 필요가 없다.
  필요로 하는 정보를 찾은 후에는 바로 파싱의 과정을 종료할 수 있다.

- SAX parser의 생성
  . SAX parser의 구성
    Parser
 XMLReader
 ContentHandler, ErrorHandler

  . XMLReader의 생성
    XMLReader reader = XMLReaderFactory.createXMLReader();

  . ContentHandler
    10여개 정도의 event(startElement, endDocument...) 정의

  . ErrorHandler
    3개의 event(warning, error, fatalError) 정의

  . DefaultHandler
    이벤트마다 interface에 정의된 메소드들을 구현해야 하는 번거로움을 제거.

 public class DataProcessor extends DefaultHandler {
  public DataProcessor() {
   super();
  }
 }

 public class ErrorProcessor extends DefaultHandler {
  public ErrorProcessor() {
   super();
  }

  public void error(SAXParseException e) {
   System.out.println("Error : " + e.getMessage());
  }

  public void fatalError(SAXParseException e) {
   System.out.println("Fatal Error : " + e.getMessage());
  }

  public void warning(SAXParseException e) {
   System.out.println("Warning : " + e.getMessage());
  }
 }

 warning : 오류로 취급되지는 않지만 사용자에게는 전달할 필요가 있는 항목.
 error   : XML 1.0 권고안에서 정의한 오류들. 오류 발생시 파서는 더 이상 실행되지 않음.
 fatal error : 오류로 인해 파서의 계속적인 수행이 불가능하면 발생.

 DTDHandler     : 내부 DTD에서 정의되는 notation과 parsing 되지 않는 entity들에 대한 통지 수신
 DeclHandler    : DOCTYPE과 관련된 기타 event에 대한 통지 수신
 LexicalHandler : startDTD와 endCDATA 같은 이벤트들에 대한 통지 수신

  . Handler 설정
    XMLReader reader = XMLReaderFactory.createXMLReader(parserClass);
    reader.setContentHandler(new DataProcessor());
 reader.setErrorHandler(new ErrorProcessor());

  . 문서의 parsing
    InputSource file = new InputSource("votes.xml");
    reader.parse(file);

 InputStrea, Reader, String 모두 파서의 입력으로 이용 가능

- event의 처리

  . Document event
    public void startDocument() {}
 public void endDocument() {}

  . Element event
    public void startElement(String namespaceUri, String localName, String qualifiedName, Attributes attributes) {
  attributes.getLocalName(int i);
  attributes.getQName(int i);
  attributes.getValue(attributes.getQName(int i));
 }
    public void endElement(String namespaceUri, String localName, String qualifiedName) {}

  . Text event
    SAX에서 text contents는 element event가 아닌 characters event를 통해 전송된다.

 StringBuffer thisText = new StringBuffer();
 public void characters(char[] ch, int start, int length) {
  thisText.append(ch, start, length);
 }

 public void ignorableWhitespace(char[] ch, int start, int length) {}

  . startPrefixMapping(String prefix, String uri)
    namespace가 범주에 포함될 때 발생
  . endPrefixMapping(String prefix)
    namespace가 범주를 벗어날 때 발생
  . processingInstruction(String target, String data)
    parser가 처리 지시문에 접근했을 때 발생
  . skippedEntity(String name)
    parser과 외부 entity를 발견할 때 발생

- filter and chain

  . filter
    parser와 contents handler 사이에 위치
 데이터 처리 이전에 filter를 사용하여 application에 적합한 데이터로 변경

 parse -> filter -> content handler -> application

  . XMLFilter 생성
    public class DataFilter extends XMLFilterImpl {
  public DataFilter() {
  }

  public DataFilter(XMLReader parent) {
   super(parent);
  }
 }

 XMLFilterImpl은 DefaultHandler 클래스의 method 뿐만 아니라 XMLReader의 모든 method들도 구현한다.
 XMLFilterImpl은 DefaultHandler, XMLReader 두 class 모두의 역할을 수행

  . Stream에 filter의 삽입
    XMLFilter filter = new DataFilter();
 filter.setParent(reader);
 filter.setContentHandler(new DataProcessor());
 filter.setErrorHandler(new ErrorProcessor());
 filter.parse(new InputSource("votes.xml"));

  . Data의 filtering
 method를 overide 해서 사용한다.


'그거 > Tech' 카테고리의 다른 글

07.DTD(Document Type Definition)  (0) 2007.02.15
06. XML 문서에 대한 유효성 검증  (0) 2007.02.15
04. DOM의 활용(고급편)  (0) 2007.02.14
03. XML 문서의 처리 - DOM  (0) 2007.02.14
02. XML 문서와 application의 설계  (0) 2007.02.14
:
Posted by 뽀기
2007. 2. 14. 17:48

04. DOM의 활용(고급편) 그거/Tech2007. 2. 14. 17:48

- 문서 내 노드를 추출하는 방법
  . NodeList를 생성한 후, 이 list의 길이만큼 반복하여 list에 저장된 노드들을 추출
    : 우선 루트 엘리먼트의 자식 엘리먼트들에 대한 NodeList를 생성하고, 이 list의 길이만큼 for 문을 반복적으로 수행
   for( int i = 0 ; i < childNodeList.getLength() ; i++ ) {
     Node thisNode = childNodeList.item(i);
  ....
   }
  . 노드의 형제 관계성을 통하여 추출
    : 먼저 첫 번째 자식 노드에 접근한 후, 접근한 노드의 형제 노드로 이동하고, 더 이상 이동할 형제 노드가 없을 때 까지 반복된다.
   for( Node child = root.getFirstChild() ; child != null ; child = child.getNextSibling() ) {
     Node thisNode = node;
   }

- DOM 트리의 모든 노드들의 노드 타입과 이름, 값을 출력
  public void stepThrouch(Node thisNode) {
    int type = thisNode.getNodeType();
    String name = thisNode.getNodeName();
    String value = thisNode.getNodeValue();

 for(Node child = thisNode.getFirstChild() ; child != null ; ) {
   child = child.getNextSibling();
   stepThrouch(child);
 }
  }

  (9) #document:null   <--- 문서 자체
  (10) airlocksystem:null <-- DOCTYPE 선언
  (7)xml-stylesheet:href="airlocks.xsl" type="text/xsl" <--스타일 시트 선언
  (1)airlocksystem:null <-- root element
  (3)#text:

  (1)airlock:null
  (3)#text:

  (1)size:null
  (3)#text:

  (1)type:null
  (3)#text:Bronson
  (3)#text:

  (1)location:null
  (3)#text:Level 2 aft
  (3)#text:

  (1)status:null
  (3)#text:open
  (3)#text:

  (1)maintenance:null
  ....


- 정규화와 규범화
  정규화 : 텍스트 노드의 문제를 해결하기 위해서 일정한 형식을 만족하도록 XML 문서를 구성하는 작업
  규범화 : 동일한 정보에 대한 서로 다른 표현들에 대허서 XML의 처리에 도움을 주고, XML 문서 자체에서는 명시되지 않은 표현의 차이에 대해서 동일 정보에 대한 동일 표현을 가지도록 한다.
    규범적 XML 문서의 조건
 . XML 선언부와 DTD는 반드시 제거되어야 한다.
 . attribute는 알파벳 순서에 맞추어 정렬한다.
 . namespace 선언문은 적용 가능한 모든 element의 집합 중에서 가장 바깥쪽의 element에만 정의한다.
 . text node에서 <, &, >, #xD 등의 문자들은 각각 &lt; &amp; &gt; &#xD;로 대체한다.
 . attribute node에서 <, &, " 등의 문자들은 각각 &lt; &amp; &quot 등으로 대체한다.
 . element의 시작 태그 내에 있는 공백 문자들은 모두 삭제되어야 한다.


- DOM level 2.0 Traversal
  DOM 트리를 순회하는 기능을 제공

  Node root = doc.getDocumentElement();
  DocumentTraversal traversal = (DocumentTraversal)doc;
  NodeIterator nodeItrator = traversal.createNodeIterator(1, 2, 3, false);
   
 createNodeIterator(1, 2, 3, false);
    1 : 순회할 노드
 2 : 상수 필터, NodeFilter.SHOW_ALL = 모든 노드를 포함하여 순회
                NodeFilter.SHOW_ELEMENT = 요소만 순회
       NodeFilter.SHOW_TEXT = 텍스트 노드만 순회
    3 : NodeFilter 구현 객체
 false : entity 참조의 실제값을 분석할 것인가?
  
 class FormattingNodeFilter implements NodeFilter {
  public short acceptNode(Node n) {
   if (n.getNodeType() == Node.TEXT_NODE) {
    Node parent = n.getParentNode();

    if ((parent.getNodeName().equalsIgnoreCase("b")) ||
     (parent.getNodeName().equalsIgnoreCase("i"))) {
     return FILTER_ACCEPT;
    }
   }

   return FILTER_SKIP;
  }
 }
 aceptNode(Node n);
 NodeFilter.FILTER_SKIP = 필터로 들어온 노드는 건너뛰고 그 자식노드를 계속 탐색
 NodeFilter.FILTER_REJECT = 필터로 들어온 노드와 그 자식 모두 건너뜀
 NodeFilter.FILTER_ACCEPT = 필터로 들어온 노드 사용

- DOM level 3.0 Load and Save
  XML 문서의 적재
   1. factory method를 포함하는 DOMImplementationLS를 생성한다.
   2. DOMBuilder를 생성한다.
   3. 소스를 명시하기 위해 DOMInput을 생성한다.
   4. DOMInput으로 명시된 소스 문서를 파싱하기 위해 DOMBuilder를 사용하고, DOM Document를 반환한다.

   DOMImplementationLS DOMLS = new DOMImplementationImpl();
   DOMBuilder db = DOMLS.createDOMBuilder(1);
   DOMInputSource dinput = DOMLS.createDOMInputSource();
   dinput.setSystemId("airlocks.xml");
   doc = db.parse(dinput);

  XML 문서의 저장
   DOMWriter dw = DOMLS.createDOMWriter();
   DOMOutputStream doutput = DOMLS.createDOMOutputStream();
   doutput.setSystemId("output.xml");
   dw.writeNode(doutput, doc.getDocumentElement());

'그거 > Tech' 카테고리의 다른 글

06. XML 문서에 대한 유효성 검증  (0) 2007.02.15
05. XML 스트림 (SAX)  (0) 2007.02.14
03. XML 문서의 처리 - DOM  (0) 2007.02.14
02. XML 문서와 application의 설계  (0) 2007.02.14
01. XML 문서의 기본 구조  (0) 2007.02.14
:
Posted by 뽀기
2007. 2. 14. 17:48

03. XML 문서의 처리 - DOM 그거/Tech2007. 2. 14. 17:48

DOM ( Document Object Model)

DOM level 0 : HTML ver.3.x를 대상으로 한 비공식 버전
DOM level 1 : Node, Element, Attribute로 구성되는 기본 구조
DOM level 2 : DOM level 1의 보강
DOM level 3 :

- Node
  DOM의 기본 구성 요소
  문서 그 자체, element, attribute, text, 처리 지시문, 주석문 등이 모두 Node interface의 특별한 경우로 인식됨

  <?xml version="1.0"?>
  <friend>
   <handle degree="close">Harold</handle>
  </friend>

  하나의 문서 노드
  두 개의 element 노드(friend와 handle)
  네 개의 텍스트 노드(close, Harold, handle element의 앞/뒤 줄바꿈)
  하나의 애트리뷰트 노드(degree)

  document - root element(firned) +-  text(whitespace)
                                               +-  element(handle)      - text(Harold)
                                               |    |
                                               |    +- attribute(degree) - text(close)
                                               +- text(whitespace)

- DOM에 정의된 interface
  Node                     - 모든 노드 타입에 대한 상위 클래스. getParentNode(), getNodeName(), insertBefore(), removeChild()...
  Document                 - 거의 모든 타입의 노드들을 포함하는 노드, 문서 자체를 대표하는 interface. createElement(), createTextNode() ...
  Element                  - element를 대표하는 타입. Attr 노드와 관련될 수 있는 노드 타입. getElementsByTagName() ...
  Attr                     - 자식으로 Text 노드나 EntityReference 노드를 가질 수 있다.
  Text                     - 마크없이 없는 문자열. 혼합 컨텐츠에 대한 텍스트 노드는 Text와 Element 노드로 분리될 수 있다.
  CDATASection             - 마크업 기호(<, >)를 단순한 텍스트로 취급
  DocumentType             - DTD 내부에 문자열로 표현된 모든 정보를 포함하는 노드 타입.
  Comment                  -
  Notation                 -
  Entity                   -
  EntityReference          -
  ProcessingInstruction    -

  DocumentFragment         - 이 Node 인터페이스의 구현은 자신의 고유 메소드를 갖는 대신에 옮기고자 하는 노드의 그룹을 포함하는 컨테이너나 작은 문서의 역할
  DOMImplementation        - hasFeature() 메소드를 사용해서 지원되는 기능의 가동 여부를 확인할 수 있다.
  DOMException, ExceptionCode - application 에서 발생한 예외 사항에 대한 보고를 위해 사용.
  NodeList                 - Node의 자식들처럼 정렬된 목록을 제공
  NamedNodeMap             - 한 element가 포함하는 attribute들 처럼 이름에 의해 접근 가능한, 정렬되지 않은 목록을 제공.

- DOM 관련 권고안들
  DOM level 2.0 Traversal and Range
    : XML 문서에 대한 효율적인 조회를 위한 NodeItreator 와 TreeWalker의 두 가지 새로운 interface가 포함.
  DOM level 2.0 HTML
    : Core 권고안 내에 HTMLDocument와 HTMLFormElement와 같은 HTML 문서에 대한 정의를 포함.
  DOM level 2.0 Style Sheets
    : CSS나 CSS 내부에 포함된 데이터의 처리를 위한 interface에 대한 정의를 제공.
  DOM level 2.0 Views
    : 문서의 버전을 구별하는 방법을 제공(DOM level 3.0 에서 삭제된 모듈)
  DOM level 2.0 Events
    : 마우스 클릭과 같은 액션이 발생했을 때 객체의 행동을 결정하는 방법을 제공하며, 해당 객체의 상휘/하위의 모든 객체에 영향을 미친다.
  DOM level 3.0 Load and Save
    : 문서의 적재와 저장에 대한 interface를 제공.
  DOM level 3.- Validation
    : Document 객체가 특정 문법과 연관되어 유효성을 갖는지 검사하는 방법을 제공.
  DOM level 3.0 XPath
    : 문서 내에서 노드의 위치를 찾아내거나 기술하기 위해 XPath 문법을 사용해 높은 유연성을 제공. DOM 에서의 XPath 1.0 이용 방법을 정의

- DOM interface 구현
  Java => JAXP, Apache, Xerces-Java
  C++  => MS Visual C++ .NET - COM과 MSXML 4.0
  VB   => MS VB .NET - MSXML 4.0
  Perl => Apache Xerces
  PHP  => PHP 4.2.1 또는 이후 버전

- Java를 이용한 XML 문서의 파싱

  import javax.xml.parsers.DocumentBuilder;
  import javax.xml.parsers.DocumentBuilderFactory;
  import java.io.File;
  import org.w3c.dom.Document;
  import org.w3c.dom.DOMImplementation;

  public class ActivityListing {
   public static void main(String[] args) {
  File docFile = new FIle("activities.xml");
  Document doc = null;

  try {
   DocumentBuilderFactory dbf = DocumentBuilderFactory.netInstance();
   DocumentBuilder db = dbf.newDocumentBuilder();
   doc = db.parse(docFile);

   DOMImplementation domImpl = doc.getImeplementation();

   if( domImpl.hasFeature("Core", "2.0") ) {
    System.out.println("2.0 is supported");
   } else {
    System.out.println("2.0 is not supported");
   }

   if( domImpl.hasFeature("Core", "5.0") ) {
    System.out.println("5.0 is supported");
   } else {
    System.out.println("5.0 is not supported");
   }
  } catch(Exception e) {
   System.out.println("Problem parsing the file.");
  }
 }
  }
 
  ELEMENT_NODE                = 1
  ATTRIBUTE_NODE              = 2
  TEXT_NODE                   = 3
  CDATA_SECTION_NODE          = 4
  ENTITY_REFERENCE_NODE       = 5
  ENTITY_NODE                 = 6
  PROCESSING_INSTRUCTION_NODE = 7
  COMMENT_NODE                = 8
  DOCUENT_NODE                = 9
  DOCUMENT_TYPE_NODE          = 10
  DOCUMENT_FRAGMENT_NODE      = 11
  NOTATION_NODE               = 12

- Document
  Element
  Child   - 아래 level
  Sibling - 같은 level
  getFirstChild()
  getNextSibling()
  getElementsByTagName()
  getElementById()
  getOwnerDocument()
  .
  .
  .
  .

  API 참조
  javax.xml.*
  org.w3c.dom(interface 정의들)
  org.xml.*

'그거 > Tech' 카테고리의 다른 글

05. XML 스트림 (SAX)  (0) 2007.02.14
04. DOM의 활용(고급편)  (0) 2007.02.14
02. XML 문서와 application의 설계  (0) 2007.02.14
01. XML 문서의 기본 구조  (0) 2007.02.14
유닉스 팁: 10가지 유닉스 사용 습관 (한글)  (0) 2007.02.08
:
Posted by 뽀기
2007. 2. 14. 17:47

02. XML 문서와 application의 설계 그거/Tech2007. 2. 14. 17:47

- 목적과 목표의 정의

  . 목적
    : 프로젝트의 수행으로 얻고자 하는 모든 결과
  . 목표
    : 목적을 달성하기 위한 측정 가능한 중간 과정

    -----------------------------------------+--------------------------------------------------------------
                                     목적                      |                        목표
    -----------------------------------------+--------------------------------------------------------------
    . 리조트와 리조트 주변 시설의 안정성에       | . 관리 스케줄과 결과를 구체화하고 이를 공지한다.
   대한 방문객들의 인식을 개선하다.                | . 관리 표지판을 개선한다.
                                                                 | . 관리 기간이 지난 장비들은 자동으로 사용을 금한다.
                                                                 | . 관리 기간 동안 이벤트 스케줄을 금지한다.
    ----------------------------------------------+---------------------------------------------------------
 . 방문객의 유람과 이벤트에 대한                    | . 방문객들이 온라인상으로 스케줄을 만들 수 있도록 지원한다.
   참여도를 높이다.                                       | . 사용자들이 리조트 관계자와 직접 만나지 않더라도
                                                                 |   온라인으로 예약 가능하도록 한다.
                                                                 | . 과거의 경험이나 선호도 등을 바탕으로 방문객의 공간에
                                                                 |   개인 취향에 맞는 광고를 싣는다.
    -----------------------------------------+--------------------------------------------------------------
  
- Data Modeling
  . 개체(Entity)
    : 필요로 하는 정보에 대해 물질적 또는 관념적으로 중요한 개념
  . 속성(Attribute)
    : 개체의 특성이나 상태를 나타낸다.
  . 관계성(Relationship)
    : 두개의 entity의 연결 상태를 설명한다.


'그거 > Tech' 카테고리의 다른 글

05. XML 스트림 (SAX)  (0) 2007.02.14
04. DOM의 활용(고급편)  (0) 2007.02.14
03. XML 문서의 처리 - DOM  (0) 2007.02.14
01. XML 문서의 기본 구조  (0) 2007.02.14
유닉스 팁: 10가지 유닉스 사용 습관 (한글)  (0) 2007.02.08
:
Posted by 뽀기
2007. 2. 14. 17:46

01. XML 문서의 기본 구조 그거/Tech2007. 2. 14. 17:46

- XML 문서는 element와 attribute 들의 부모-자식 관계를 갖는 계층 구조로 표현된다

##############################################

- 파일 구조
  well-formed

  XML 선언부(필수)
    <?xml version="1.0" encoding="EUC-KR" standalone="no"?>
  DOCTYPE 선언부(선택)
    <!DOCTYPE airlocksystem SYSTEM "airlocks.dtd">
  root element
    has only one.

- Element
  시작 태그, 문자 데이터, 종료 태그
  element의 이름은 element를 정의하는 마크업의 중요한 특징
  element 이름 지정 규칙
   . 문자 또는 '_' 로만 시작 가능하다.
   . 시작 태그와 종료 태그의 이름은 반드시 일치
   . : 을 포함할 수 없다.
   . 공백이 있어서는 안된다.

- Attribute
  elememt에 추가 정보를 기술하기 위해 시작 태그 내에 추가한 이름-값 쌍
  attribute 이름 지정 규칙
   . element 이름과 동일한 규칙을 따른다
   . 동일 element 내에서 attribute 이름은 유일해야 한다.

- Entity
  & 와 ; 를 이용하여 표현되는 값
  &lt; = <
  &gt; = >
  &amp; = &
  &quot; = "
  &apos; = '

- CDATA
  character data
  attribute 값과 마찬가지로 XML application에 의해서 parsing 되지 않는 값

- 처리 지시문
  XML 데이터를 처리하는 application에 전달항 정보를 기입
  <? .... ?>
  XML 선언부의 <? ?>는 처리 지시문이 아니다.

- 주석문
  <!-- ... -->

##############################################

- well-formed XML documenet vs valid XML document
 . well-formed XML document
   : XML 문서가 기본적으로 갖춰야 할 요구 조건을 만족하는 문서.
     그러나 어떤 element가 어떤 타입의 컨텐츠를 가지든지,
     어떤 순서로 표현해야 하는지에 대한 제약은 없다.
 . valid XML document
   : DTD 내의 element와 attribute 들에 대한 정의(이 정의에는 컨첸츠 타입, 출현 순서 등이 포함된다)를 준수하는 문서
 
- pre-requsite for well-formed XML document
  . XML 문서는 문서 내의 다른 모든 element를 포함하는 단일한 root element를 가져야 한다.
  . 모든 element는 올바르게 중첩되어야 한다. 임의의 element 내에서 시작 태그를 갖는 element는 반드시 동일한 element 내에 종료 태그를 가져야 한다.
  . 모든 attribute의 값은 반드시 인용 부호로 둘러싸여야 한다.
  . attribute 값은 < 문자를 포함할 수 없다.
  . 하나의 element는 이름이 다른 여러 개의 attribute를 가질 수 있다. 하지만 같은 이름의 여러 attribute를 가질 수 없다.
  . XML 문서 내의 모든 문자는 적법한 문자여야 한다.
    XML 문서에서 적법한 문자란 유니코드 표준에서 정의한 65,000개 이상의 문자를 뜻한다. 하지만 이러한 문자를 이용하기 위해서는
 먼저 문서 내에서 문자 인코딩 체계를 정의해야 한다.
 만약 독자가 어떤 XML 문서의 인코딩 체계를 ISO 8859-1로 정의했다면, 이 인코딩 체계에 따른 문자 집합 내의 문자만 이용해야 한다.
  . attrivute 값은 외부 entity를 참조할 수 없다.
  . parameter entity라 불리는 특정 타입의 entity 들은 DTD 내에서는 참조될 수 있지만, XML 문서 내에서는 참조 될 수 없다.
  . parameter entity는 자신을 참조할 수 없다.
  . parsed entity는 그래픽 파일처럼 unparsed entity에 대한 참조를 포함할 수 없다.

##############################################

- namespace
  . 언제든지 단일 이름으로 변수, 함수 파일 등과 같은 아이템에 대해 유일하고 중복되지 않는 참조를 가능하게 가는 것
  . 이름으로 인한 혼동을 없애기 위해 고안됨.
  . 여러 XML 문서의 element를 조합해서 다른 XML 문서를 작성할 때 혼동을 없애기 위해 namespace를 사용한다.

  . namespace 지정
    : xmlns:NameSpace="URI"
  . default namespace
    : xmlns="URI"
  . namespace 삭제
    : xmlns=""

'그거 > Tech' 카테고리의 다른 글

05. XML 스트림 (SAX)  (0) 2007.02.14
04. DOM의 활용(고급편)  (0) 2007.02.14
03. XML 문서의 처리 - DOM  (0) 2007.02.14
02. XML 문서와 application의 설계  (0) 2007.02.14
유닉스 팁: 10가지 유닉스 사용 습관 (한글)  (0) 2007.02.08
:
Posted by 뽀기

애플리케이션에 맞게 데이터를 인코딩(encode) 하는 가장 올바른 방법


JavaScript가 필요한 문서 옵션은 디스플레이되지 않습니다.



난이도 : 중급

Dethe Elza, Senior Software Developer, Uniserve Communications Corporation
David Mertz, Ph.D, Author, Gnosis Software, Inc.

2007 년 2 월 06 일

Ajax(Asynchronous JavaScript and XML)는 신뢰성을 기반으로, 서버에 채널을 개방하여, 웹 애플리케이션에서 사용되는 데이터를 교환하는 신개념 웹 브라우저입니다. 이것은 표준 웹 기술과는 반대되는 개념이고, Ajax를 기반으로 개발 할 때, 전통적인 웹 페이지들과는 다른 디자인 정책이 필요합니다. 백(back) 버튼을 관리하는 방법, 업데이트 된 데이터를 디스플레이 하는 방법, 업데이트를 보내는 빈도수 등도 그 예가 될 수 있습니다. 이 글에서는 데이터 교환에 어떤 포맷을 사용해야 할 것인지를 중점적으로 설명합니다.

Ajax라는 단어에서 X는 XML을 뜻하지만, XML은 언어가 아니라 언어를 구현하는 툴킷이다. 따라서, 가장 먼저, 기존 언어를 사용할 것인가, 아니면 자신의 언어로 재 구축할 것인지를 결정해야 한다. 결정하고 나서는 부가적인 문제들이 생기기 시작한다. 기존의 언어들은 자신의 필요에 맞는가, 자신에 필요에 맞게 설계할 수 있는가? 그 언어를 처리할 툴은 있는가, 툴을 구현해야 하는가? 다른 사람들과 커뮤니케이션을 해야 한다면, 그 언어는 잘 알려진 언어인가? 다른 애플리케이션들도 쉽게 여러분의 데이터에 액세스 하여, 사용할 수 있는가?

그래픽 데이터일 경우에는 (X)HTML, SVG 또는 X3D, 데이터 조각에는 Atom, 단순한 아웃라인에는 OPML, 그래프에는 RDF 등 용도가 확실한 것도 있다. 완벽한 기능을 갖추고 있고, 장황한 DocBook, DITA, OpenOffice 포맷으로 된 데이터를 보낼 수도 있다. (참고자료)

한편, Ajax라는 단어에서 X가 무엇을 뜻하는지에 상관없이, 여러분이 원하는 다양한 종류의 데이터를 보낼 수 있다. 바이너리 데이터, 이미지, 무비, PDF 파일도 가능하지만, JavaScript로 되어있는 브라우저에서는 다루기 어렵다. XML 보다 단순한 텍스트 포맷으로 보낼 수도 있다. Tab 또는 콤마 분리 리스트(tab-, comma-delimited list), Markdown, YAML, JSON 등을 XML 대안으로 사용할 수 있다. 이외에도, XML을 사용하지 않는 수 십 개의 옵션들이 있다. (참고자료 - XML Alternatives 웹 사이트 참조) 물론, 장황함(verbose)과 풍부함(rich)의 차이는 있다. 심지어, 이 리스트에 있는 한 개의 아이템에서도 여러 가지의 데이터 인코딩 방식이 있을 수 있다.

  • OpenOffice Spreadsheet
  • DITA (Darwin Information Typing Architecture)
  • DocBook
  • RDF-XML
  • XHTML
  • Microformat
  • Atom
  • OPML (Outline Processor Markup Language)
  • Custom XML
  • Markdown / Textile / reStructured Text
  • YAML (YAML Ain't Markup Language)
  • JSON (JavaScript Object Notation)
  • Comma- (or Tab-) delimited text

무엇을 선택하여야 하는가?

이러한 많은 옵션들 중에서, 어떻게 하면 현명한 결정을 내릴 수 있을까? 위에 제시한 리스트는 엄밀히 말해서 복잡한 순서대로 나열한 것은 아니다.

  • 우선, 가장 단순한 방식 또는 가장 복잡한 방식으로 포맷을 사용할 수 있다.
  • 생성, 읽기, 파싱, 프로세스 중에서 어떤 것이 가장 복잡한 것인지를 파악해야 한다. 예를 들어, XML은 그 자체로 복잡한 편이지만, 파서가 브라우저에 이미 있기 때문에 파싱은 오히려 단순하다.
  • 복잡성은 데이터의 유형에 상당히 많이 의존한다. 스프레드시트나 데이터베이스처럼, 고정된 구조를 갖고 있는가? 워드 프로세싱 문서나 블로그 포스트처럼 유연한(loosely) 구조를 갖고 있는가? 항공기 매뉴얼 같은 대형 문서인가, 응답 코드 같은 작은 데이터 조각인가? 데이터 세트가 크다면, 이것을 한 번에 보낼 것인가, 아니면 필요할 때마다 작은 조각 단위로 보낼 것인가? 큰 데이터를 작은 조각 단위로 나누는 것은 얼마나 어려우며, 받는 쪽에서, 작은 조각들을 올바르게 조합하려면 얼마나 많은 정보가 필요한가?

즉, 무엇이 가장 중요한 요소인가?

  • 장황함/대역폭(특별한 경우를 제외하고는, 이러한 요소는 여러분이 생각하는 것만큼 중요하지 않다.)
  • 가독성(작성 가능성, 관리성)
  • 파싱 난이도(클라이언트 측과 서버 측)
  • 파싱 속도(네이티브 대 스크립팅)
  • 정보 손실(ordered pairs -> dictionary -> sets)
  • 유연성(가끔은, 덜 유연한 것이 더 나을 때도 있다.)
  • 언어 이식성(얼마나 많은 언어들을 사용할 수 있는가?)
  • 정확성(포맷에 어느 정도 순응하는가?)
  • 라운드 트리핑 (Round-Tripping) (Markdown -> XHTML -> Markdown, 얼마나 많은 데이터 손실이 있는가?)

속도, 대역폭 활용, 효율성을 위해서가 아니라, 사용자를 만족시키기 위해 최적화 하는 경우가 대부분이다. 지연되는 부분은 숨기고, 즉각적인 업데이트가 가능하다면, 미미한 네트워크 지연은 문제가 되지 않는다. 바로 이것이 Ajax의 가장 큰 장점일 것이다.




위로


제 1 원칙

이 글에서, 몇 가지 선택 원칙을 제시하고, 이를 뒷받침 할 몇 가지 예제도 소개하겠다. 이모든 것들이 여러 가지 옵션들을 선택하는데 있어서 충실한 가이드라인이 될 것이다.

  • 데이터용 JSON: 데이터가 구축되었다면 JSON이 제격이다. 적어도 세 개의 파서들이 브라우저에 포함되어 있고(HTML, XML, JavaScript), 이중 가장 빠른 것은 JavaScript 이다. 또한, 데이터가 이미 JavaScript로 되어 있을 경우, JavaScript를 사용하여 데이터를 조작하는 것이 DOM 보다는 낫다. 데이터를 바로 디스플레이 하지 않거나, 데이터가 먼저 수정되어야 한다거나, 또는 데이터가 웹 페이지의 다른 부분에서, 또는 다른 포맷으로 디스플레이 된다면, JSON이 잘 맞는다. 대부분의 언어들에는 JSON용 라이브러리가 있기 때문에, 더 이상 JavaScript만을 위한 것은 아니다.
  • 혼합 콘텐트(문서)를 위한 XML: URL과 같은 메타데이터를 사용하거나, 워드 프로세싱 문서와 블로그 포스트 같은 마크업과 텍스트를 혼합해야 한다면 XML을 사용하라. 데이터가 한 곳에서 직접 디스플레이 된다면, 서버에서 이를 정형화(format)하고, Ajax를 사용하여 검색 및 삽입한다.(이 기법은 'client-side includes'라고 알려졌다.) David가 "MochiKit" (참고자료)에서 언급하였듯이, XML을 브라우저로 전달하고 CSS로 포맷하거나, 또는 HTML을 통해서 이를 스타일링 할 것인지를 선택할 수 있다. 당신이 XML을 사용해야 한다면, 필자는 XHTML, SVG, X3D등과 같은 표준 포맷을 사용하라는 것 외에 많은 가이드라인을 줄 수는 없다. 이러한 포맷들의 서브셋을 사용하여, 시스템들 간 상호 운용성이 뛰어난 데이터를 만들 수 있고, 다른 프로그래머들도 익숙하게 사용할 수 있도록 한다. 가끔은 자신만의 XML 포맷을 만들 수도 있지만, 상호 운용성 부분에서는 더욱 많은 신경을 써야 한다. 그것도 의심스럽다면, HTML을 계속 사용하라.
  • 동기화(Syndication)를 위한 Atom: 여기에서 나는 동기화에 대해 매우 포괄적으로 정의를 내리고자 한다. 데이터를 주기적으로 업데이트 할 것이라면, 데이터에 타임스탬프가 필요하다면, Atom을 사용하는 것이 좋다. 또한, 데이터 흐름에 대한 표준 인벨롭(envelope)으로서 Atom 포맷을 사용하는 것이 좋다. 이렇게 하면, 애그리게이터(aggregator), 뉴스 리더기, 스크립팅 라이브러리를 통해서, 데이터를 추적하고 재사용할 수 있는 많은 툴들을 사용할 수 있을 것이다. 또한, 웹 페이지에 데이터를 삽입만 하면, 크게 노력하지 않아도 동기화 피드가 될 수 있는 효과도 누릴 수 있다.



위로


선택의 파라독스

이제, 다른 포맷들과, 각 포맷의 사용 방법에 대해서 알아보자. 이전 두 개의 칼럼에서는(참고자료) 메커니즘에 초점을 맞추느라 간단한 예제를 사용했지만, 이번에는 실제 예제를 사용해보겠다. 나의 아내인 Daniela는 시인이다. 그녀는 잡지, 콘테스트, 이벤트에 제출한 작품들을 관리해야 했다. 제출한 시가 어떤 단계에 와 있으며, 어떤 것이 채택 또는 탈락 되었는지, 각 작품당 가격은 얼마인지, 이벤트 비용은 얼마인지를 알아야 한다. Listing 1은 데이터 내용이다.


Listing 1
				

Room of One's Own
Submitted May 10, '05
* Hyacinth Blue
* Fabrication
* Thanksgiving
* Spilling the Peas
Accepted Hyacinth Blue
Accepted Sept 2005
Published Oct 2006
Paid Sept 2006
Paid $50 + 2 copies
Postage $1.12
Submission Fee: 0
Journal submission

Surrey International Writer's Contest
Contest submission
Submitted Aug. 31 2006
* 13th Child
Fee: $15
Postage: 1.05
Honorable Mention
Prize: $150 + copy of anthology
Accepted Sept. 26 2006
Publication Date Oct. 20 2006

Word on the Street
Public Reading
Invited speaker
Reading time: 10 minutes
Paid: T-shirt and lunch
Date: Sept 24 2006

Paideusis: The Journal of the Canadian Philosophy of \
    Education Society
Submitted Oct. 13th 2006
* To carry over: metaphor invents us (seven poems)
Email submission
Referreed Journal
Accepted Oct. 16th 2006
Published (Pending) Nov. 2006


어느 정도 까지는 이러한 포맷도 유효했지만, 출품작이 많아지면서, 트래킹(tracking)은 더욱 어려워졌다. 연간 수입과 지출을 가늠하기가 더 어려워졌고, 평균 응답 시간(제출과 채택 또는 탈락까지 걸리는 시간)같은 정보도 받아보고 싶었다. 그래서, 나는 아내에게 "Fame Not Fortune"이라고 하는, Ajax 웹 애플리케이션을 구현 할 것을 제안했다.

물론, 나의 게으름 탓에, 새로운 애플리케이션을 구현하지 않고, 원래 있었던 애플리케이션을 사용하게 되었다. 아내가 시를 편집할 때 Open Office (워드 프로세싱) (참고자료)를 사용하기 때문에, 그림1처럼 트래킹에도 Open Office (spreadsheet)를 사용할 수 있었다.


그림 1. Open Office Spreadsheet 예제
Open Office Spreadsheet example

벌써, 몇 가지 문제가 드러나고 있다. 특히, 스프레드시트는 트래킹에 맞는 인터페이스가 아니다. 대상 데이터는 매우 유연하기 때문에, 많은 칼럼들이 채워지지 않았고, 아내도 스프레드시트를 사용하는 것에 익숙하지 않았다. 웹 애플리케이션을 구현해야 한다는 나의 생각이 옳았다. 물론, Open Office는 문서를 XML로 저장하기 때문에, 복잡한 데이터 마이닝(data-mining) 태스크에는 Open Office를 사용하고, 데이터 입력에는 웹을 사용하는 상황이다. 이러한 경우에는 한 가지 포맷을 결정하는 것이 더 낫다.

Open Office에 저장된 포맷은, 실상은 데이터와 기타 리소스들(삽입된 이미지, 스크립트, 스타일링 정보)을 포함하고 있는 .zip 파일인, .odf 파일이다. 이 문서를 보면서, 다음과 같은 사실들을 발견했다.

  • META-INF는 .odf 문서의 콘텐트 리스트인 manifest.xml을 포함하고 있는 폴더이다.
  • Configurations2는 상태 바, 메뉴 같은 UI를 포함하고 있는 폴더이다. 현재까지는 무시해도 좋다.
  • Thumbnails은 작은 .png 이미지를 포함하고 있는 폴더이다.
  • content.xml은 내가 입력했던 실제 데이터 파일이다.
  • meta.xml은 문서에 대한 정보를 포함하고 있는 파일이다. 생성자, 수정일, 기타 상세 정보를 포함하고 있다.
  • mimetype은 "application/vnd.oasis.opendocument.spreadsheet" 스트링을 포함하고 있는 파일이다.
  • settings.xml은 Open Office 설정 내용들을 포함하고 있는 파일이다.
  • styles.xml은 스프레드시트에 대한 포맷팅 정보를 포함하고 있는 파일이다.

따라서, 웹 애플리케이션과 Open Office간 데이터를 교환해야 한다면, 전체 .odf 파일이 아닌 내부 content.xml 파일에 주목해야 한다. 이 파일에는 무엇이 있을까? 17,629개의 문자와, 23개의 XML 네임스페이스, 63 줄의 스타일링 정보가 포함되어 있고, 모든 셀에는 스타일 정보가 들어있다. 이것은 데스크탑 스프레드시트 애플리케이션에는 합리적인 대안이지만, 네트워크를 통해서까지 이렇게 불필요한 정보를 처리하느라 시간을 허비하고 싶지는 않다. Listing 2는 실제 데이터의 한 행(row)이다.


Listing 2
				<table:table-row table:style-name="ro3">
  <table:table-cell office:value-type="string">
    <text:p>Room of One's Own</text:p>
  </table:table-cell>
  <table:table-cell table:style-name="Default"
  office:value-type="string">
    <text:p>Journal</text:p>
  </table:table-cell>
  <table:table-cell table:style-name="ce2"
  office:value-type="string">
    <text:p>Hyacinth Blue; Fabrication; Thanksgiving;
    Spilling the Peas</text:p>
  </table:table-cell>
  <table:table-cell table:style-name="ce5"
  office:value-type="date" office:date-value="2005-05-10">
    <text:p>10 May 2005</text:p>
  </table:table-cell>
  <table:table-cell table:style-name="ce5"
  office:value-type="date" office:date-value="2005-09-01">
    <text:p>1 Sep 2005</text:p>
  </table:table-cell>
  <table:table-cell table:style-name="ce5"
  office:value-type="date" office:date-value="2006-10-01">
    <text:p>1 Oct 2006</text:p>
  </table:table-cell>
  <table:table-cell table:style-name="ce5"
  office:value-type="date" office:date-value="2006-09-01">
    <text:p>1 Sep 2006</text:p>
  </table:table-cell>
  <table:table-cell office:value-type="string">
    <text:p>Hyacinth Blue</text:p>
  </table:table-cell>
  <table:table-cell table:style-name="ce6"
  office:value-type="currency" office:currency="CAD"
  office:value="50">
    <text:p>50.00 CAD</text:p>
  </table:table-cell>
  <table:table-cell office:value-type="string">
    <text:p>2 Copies of Publication Issue</text:p>
  </table:table-cell>
  <table:table-cell table:style-name="ce7"
  office:value-type="currency" office:currency="CAD"
  office:value="1.12">
    <text:p>1.12 CAD</text:p>
  </table:table-cell>
  <table:table-cell table:style-name="ce7" />
  <table:table-cell table:number-columns-repeated="244" />
</table:table-row>

데이터를 XHTML에 삽입하는 것은 어떨까? 이 같은 경우, 파싱이나 포맷팅을 할 필요 없이, Listing 3처럼, 직접 디스플레이 할 수 있다.


Listing 3
				<html><body><ul>
    <li><dl>
        <dt>publisher</dt><dd>Room of One's Own</dd>
        <dt>type</dt><dd>Journal</dd>
        <dt>titles</dt><dd><ul>
            <li>Hyacinth Blue</li>
            <li>Fabrication</li>
            <li>Thanksgiving</li>
            <li>Spilling the Peas</li>
        </ul></dd>
        <dt>submitted</dt><dd>2005-05-10</dd>
        <dt>accepted</dt><dd>2005-09-01</dd>
        <dt>published</dt><dd>2006-10-01</dd>
        <dt>payment received</dt><dd>2006-09-01</dd>
        <dt>titles accepted</dt><dd><ul>
            <li>Hyacinth Blue</li>
        </ul></dd>
        <dt>expenses</dt><dd><dl>
            <dt>postage</dt><dd>CAD 1.12</dd>
        </dl></dd>
        <dt>payment</dt><dd><ul>
            <li>CAD 50.00</li>
            <li>2 Copies of Publication Issue</li>
        </ul></dd>
    </dl></li>
    <li><dl>
        <dt>publisher</dt>
            <dd>Surrey International Writers' Competition</dd>
        <dt>type</dt><dd>Contest</dd>
        <dt>titles</dt><dd><ul>
            <li>The Thirteenth Child</li>
        </ul></dd>
        <dt>submitted</dt><dd>2006-08-31</dd>
        <dt>accepted</dt><dd>2006-09-26</dd>
        <dt>published</dt><dd>2006-10-20</dd>
        <dt>payment received</dt><dd>2006-10-20</dd>
        <dt>titles accepted</dt><dd><ul>
            <li>The Thirteenth Child</li>
        </ul></dd>
        <dt>expenses</dt><dd><dl>
            <dt>postage</dt><dd>CAD 1.05</dd>
            <dt>entry fee</dt><dd>CAD 15.00</dd>
        </dl></dd>
        <dt>payment</dt><dd><ul>
            <li>CAD 150.00</li>
            <li>Honorable Mention</li>
            <li>Copy of Anthology</li>
        </ul></dd>
    </dl></li>
    <li><dl>
        <dt>publisher</dt><dd>Word on the Street</dd>
        <dt>type</dt><dd>Invited Reader</dd>
        <dt>event</dt><dd>10 Minutes of readings</dd>
        <dt>event date</dt><dd>2006-09-24</dd>
        <dt>payment</dt><dd><ul>
            <li>T-Shirt</li>
            <li>Lunch</li>
        </ul></dd>
    </dl></li>
    <li><dl>
        <dt>publisher</dt><dd>Paideusis: The Journal of the
            Canadian Philosophy of Education Society</dd>
        <dt>type</dt><dd>Refereed Journal</dd>
        <dt>titles</dt><dd><ul>
            <li>To Carry Over: Metaphor Invents Us (seven poems)</li>
        </ul></dd>
        <dt>submitted</dt><dd>2006-10-13</dd>
        <dt>accepted</dt><dd>2006-10-16</dd>
        <dt>published</dt><dd>Pending</dd>
        <dt>titles accepted</dt><dd>All</dd>
    </dl></li>
</ul></body></html>

이것은 데이터를 HTML로 단순히 매핑한 것이다. 기본 스타일링이 충분하지는 않지만, 크로스 플랫폼(cross-platform) 방식으로, CSS를 사용하면 스타일링 하기가 매우 쉽고, DOM을 사용하여 데이터를 쉽게 조작할 수 있다. 추가된 HTML 코드 때문에 약간 부풀려 보이지만, 그렇게 심한 것은 아니다. 이 예제는 XOXO outline Microformat(참고자료)와 매우 비슷하고, class="outline"을 첫 번째 <ul /> 엘리먼트에 붙인다면, XOXO 아웃라인이 될 것이다. 여기에 커스텀 XML을 사용하여 콘텐트를 추가할 수 있고, 디스크립션 리스트를 <submission/> 엘리먼트로 대체했다. 하지만 이 예제의 경우, 간결함이나 가독성 측면에서는 별로 얻은 것이 없다. 간결함을 원한다면, JavaScript Object Notation (JSON)을 고려해 볼 수 있다.


Listing 4
				

    {   "publisher": "Room of One's Own",
        "type": "Journal",
        "titles": ["Hyacinth Blue", "Fabrication", "Thanksgiving",
            "Spilling the Peas"],
        "titles accepted": ["Hyacinth Blue"],
        "submitted": "2005-05-10",
        "accepted": "2005-09-01",
        "published": "2006-10-01",
        "payment received": "2006-09-01",
        "expenses": [{"postage": "CAD 1.12"}],
        "payment": ["CAD 50.00", "2 Copies of Publication Issue"]},
    {   "publisher": "Surrey International Writers' Competition",
        "type": "Contest",
        "titles": ["The Thirteenth Child"],
        "titles accepted": ["The Thirteenth Child"],
        "submitted": "2006-08-31",
        "accepted": "2006-09-26",
        "published": "2006-10-20",
        "payment received": "2006-10-20",
        "expenses": [{"postage": "CAD 1.05"},
            {"postage": "CAD 15.00"}],
        "payment": ["CAD 150.00", "Honorable Mention",
            "Copy of Anthology"]},
    {   "publisher": "Word on the Street",
        "type": "Invited Reader",
        "event": "10 Minutes of readings",
        "event date": "2006-09-24",
        "payment": ["T-Shirt", "Lunch"]},
    {   "publisher": "Paideusis: The Journal of the Canadian\
             Philosophy of Education Society",
        "type": "Refereed Journal",
        "titles": ["To Carry Over: Metaphor Invents Us \
            (seven poems)"],
        "titles accepted": "All",
        "submitted": "2006-10-13",
        "accepted": "2006-10-16",
        "published": "Pending"}
]

Listing 4를 보면, HTML 인코딩과 모두 같은 내용이지만, 이것은 JavaScript의 서브셋(subset)이기 때문에, JavaScript 객체, 리스트(list), 스트링(string)으로서 직접 데이터에 액세스 할 수 있다. 이 포맷은 단순하고 간결하며, 이전 포맷에 있는 모든 정보를 포함하고 있다. 게다가, 구조도 잘 보존하면서 Semi-structured 데이터에도 잘 맞는다. 이것으로 간결성에 대한 해결책은 얻었지만, 이것보다 더 단순해 질 수 있다. 첫 번째 예제로 다시 돌아가서, 스프레드시트에 데이터를 저장해 보자. 한 스프레드시트에서 다른 스프레드시트로 데이터를 옮기는 방식 중에는 Comma-Separated Value (CSV)가 있다. Listing 5를 보자.


Listing 5
				

"Publisher", "Type", "Titles", "Submitted", "Accepted/Rejected", \
"Published", "Payment Received", "Titles Accepted", "Payment", \
"In Kind", "Postage", "Fees"
"Room of One's Own", "Journal", "Hyacinth Blue; Fabrication; \
Thanksgiving; Spilling the Peas", 10 May 2005, 1 Sep 2005, \
1 Oct 2006, 1 Sep 2006, "Hyacinth Blue", 50.00 CAD, \
"2 Copies of Publication Issue", 1.12 CAD,
"Surrey International Writer's Competition", "Contest", \
"The Thirteenth Child", 31 Aug 2006, 26 Sep 2006, 20 Oct 2006, \
20 Oct 2006, "The Thirteenth Child", 150.00 CAD, "Honorable Mention, \
Copy of Anthology", 1.05 CAD, 15.00 CAD
"Word on the Street, Vancouver", "Invited Speaker", \
"10 Minutes of Readings", , , 24 Sep 2006, , , , "T-Shirt, Lunch", ,
"Paideusis: The Journal of the Canadian Philosophy of Education \
Society", "Refereed Journal", "To Carry Over: Metaphor Invents Us \
(seven poems)", 13 Oct 2006, 16 Oct 2006, "(Pending) Nov 2006", , \
"All", , , "Email",


Listing 5는 어느 정도까지 간결해 질 수 있는지를 보여주는 것 같다. JSON과 CSV의 중대한 차이도 보인다. CSV는 일반적인 기술이고, 결코 표준화 되어 있지 않으며, 오직 ASCII 텍스트만을 취하는 반면, JSON은 명확하게 표준화 되었으며, Unicode의 UTF-8 인코딩 사용에 대해서도 정의를 내린다. 따라서, CSV 예제의 경우 ASCII 범위 이외의 어떤 텍스트도 사용하지 않지만, JSON(그리고 XML)은 어떤 텍스트와도 잘 작동한다.




위로


Atom 연결

Atom Syndication Format은 필자, 발행일 등, Fame not Fortune의 정보와 몇 가지 중복되는 사항들이 있다. 이 모든 데이터를 하나의 피드(feed)에 놓고, XML로 포맷하고, 이와 동시에 표준 애그리게이터를 사용하여 이 내용들이 검색되도록 할 수 있다. 바로 이것이 나의 애플리케이션과 다른 툴들을 구별하는 요소가 된다. Listing 6은 Atom 피드의 모습이다. (간략하게 도입 부문만 소개하고자 한다.)


Listing 6
				

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title>Fame not Fortune</title>
  <subtitle>Recent submissions</subtitle>
  <link href="http://example.org/famenotfortune"/>
  <updated>2006-12-03T20:37:16Z</updated>
  <author>
    <name>Daniela Elza</name>
  </author>
  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
  <entry>
    <title>Hyacinth Blue</title>
    <link href="http://example.org/famenotfortune/hyacinthblue"/>
    <id>urn:uuid:68C0BAAB-C955-45F9-BDD6-21A22FC809AF</id>
    <updated>2006-12-01T20:37:16Z</updated>
    <published>2006-10-01T12:12:12Z</published>
    <category term="Journal"/>
    <content type="xhtml">
        <div xmlns="http://www.w3.org/1999/xhtml">
            <dl>
                <dt>publisher</dt><dd>Room of One's Own</dd>
                <dt>titles</dt><dd><ul>
                    <li>Hyacinth Blue</li>
                    <li>Fabrication</li>
                    <li>Thanksgiving</li>
                    <li>Spilling the Peas</li>
                </ul></dd>
                <dt>submitted</dt><dd>2005-05-10</dd>
                <dt>accepted</dt><dd>2005-09-01</dd>
                <dt>payment received</dt><dd>2006-09-01</dd>
                <dt>expenses</dt><dd><dl>
                    <dt>postage</dt><dd>CAD 1.12</dd>
                </dl></dd>
                <dt>payment</dt><dd><ul>
                    <li>CAD 50.00</li>
                    <li>2 Copies of Publication Issue</li>
                </ul></dd>
            </dl>
        </div>
    </content>
  </entry>
</feed>


Listing 6이 낯설지가 않다면, Atom Entry 엘리먼트에 데이터에 필요한 모든 필드들이 없고, 대부분의 엔트리가 <content/> 태그로 래핑된 XHTML 예제이기 때문일 것이다. published 필드와 author를 약간 변경할 수도 있었지만, published 필드의 남용일 뿐이다. 고유의 네임스페이스를 만들어서, 추가 필드로 Atom Entry를 확장할 수 있지만, 어떤 기존 애그리게이터나 피드 리더기도 그 정보를 사용할 수 없기 때문에 의미가 없다. 단순히 Atom 인벨롭으로 XHTML 예제를 래핑하여 애플리케이션에 동기화 지원을 할 수 있지만, 순수하게 데이터 지향 관점에서 본다면 Atom은 어떤 장점도 없다. 애플리케이션의 데이터를 이동할 때, Atom Entry로 래핑하고, Atom Publishing Protocol (참고자료)을 사용하면 도움이 될 것이다. Atom을 사용하고 싶다면, 데이터 포맷 선택에 제한이 생긴다. Atom <content/> 태그에는 세 가지 데이터 유형, 텍스트(JSON 포맷), HTML, XHTML이 포함된다. Atom을 먼저 확장하지 않고는, Atom에 임의의 XML 콘텐트를 삽입할 수 없다. 따라서, Atom 통합을 할 경우 다른 데이터 포맷 결정에도 영향을 줄 수 있기 때문에, 데이터에 동기화를 지원할 것인지의 여부를 먼저 결정해야 한다.




위로


예제

Ajax 웹 사이트나 웹 애플리케이션을 구현할 때 결정해야 할 것들이 많다. 기본적으로, 어떤 데이터 포맷을 사용할 것인지를 결정해야 한다. 나는 이 글을 통해서, 그러한 결정들을 내리는데 참조할 수 있는 몇 가지 제안을 했었다. 앞서 언급한 내용을 다시 반복하자면,

  • 데이터에는 JSON
  • 문서에는 XML (XHTML)
  • 신디케이션에는 Atom (Atom Publishing Protocol 지원)
공유 사이트...

digg Digg
del.icio.us del.icio.us
Slashdot Slashdot

여러 가지 대안들과 선택 원칙들을 설명했다. 물론, 모든 사안들 마다 특성을 갖고 있고, 예외는 어디에나 존재하기 때문에 어떤 것도 단정지을 수는 없다. 이 가이드라인이 나에게는 잘 맞았던 것처럼, 여러분에게도 도움이 되길 바란다. 의견이나 제안 사항이 있는 경우, 언제라도 환영한다.

기사의 원문보기



참고자료

교육

제품 및 기술 얻기

토론


필자소개

Photo of Dethe Elza

Dethe Elza는 http://livingcode.org/에서 적극적으로 활동하고 있다. 제안이나 권고 사항은 delza@livingcode.org로 보내기 바란다.


Photo of David Mertz

http://gnosis.cx/publish/를 방문하면 David Mertz(mertz@gnosis.cx)의 열정의 일면을 볼 수 있다. 어떤 제안이나 권고도 환영한다. http//gnosis.cx/TPiP/에서 그의 저서 "Text Processing in Python"을 만나볼 수 있다.



출처 : IBM developerworks
:
Posted by 뽀기