달력

5

« 2024/5 »

  • 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
  • 31
2007. 2. 22. 17:17

10. XML 문서의 변환과 응용 그거/Tech2007. 2. 22. 17:17

# XML 문서의 변환과 응용

# 문서 변환 방법

1. TrAX(Transformation API for XML)
  XSLT stylesheet를 이용해 문서 변환을 수행

# 데이터의 변환

1. XML의 입력
  TrAX : 여러 형태의 XML 데이터 입력을 처리할 수 있도록 고안됨

  Source interface 구현

  StreamSource source = new StreamSource("events.xml");

2. 변환 결과의 출력
  문서 변환의 결과는 문서 입력의 형식에 따라 여러 가지 형식을 가질 수 있으며,
  이러한 변환 결과의 출력을 위해 Result interface를 이용

  StreamResult result = new StreamResult("transform.html");

3. TransformerFactory
  문서의 변환을 위한 Transformer 객체를 생성하기 전에 TrasnformerFactory class를 이용한다.

  TransformerFactory transFactory = TransformerFactory.newInstance();

4. stylesheet의 선택
  Transformer 객체는 하나의 특정 stylesheet에 기반을 두고 있기 때문에,
  Transformer 객체를 생성하기 전에 문서 변환에 이용할 stylesheet를 지정해야 한다.

  StreamSource style = new StreamSource("style.xml");

  하지만, XML 문서내에 여러 종류의 stylesheet를 이용할 경우 문제가 되기 때문에 다음과 같이 수정한다.

  Source style = transFactory.getAssociatedStylesheet(source, null, null, null);

  getAssociatedStylesheet(StreamSource, media attribute, title attribute, charset attribute)
    : XML 문서 내 XSLT 처리 지시문의 media, title, charset attribute를 기반으로 stylesheet 문서를 선택할 수 있도록 한다.

5. Transformer 객체의 생성과 문서 변환
  TransformerFactory에서 Transformer 객체를 생성할 때는 문서 변환에 필요한 모든 규칙들을 포함하고 있는 stylesheet 문서를 Transformer 객체에 전달해야 한다.
  stylesheet를 지정하지 않을 경우 출력 결과는 입력 XML 문서와 동일한 문서가 된다.

  Transformer trans = transFactory.newTransformer(style);
  trans.transform(source, result);

# template과 parameter
  Templates 객체를 이용하여 여러 파일에 대해 문서 변환 수행시 Transformer를 미리 compile 시켜 두고 사용하면 처리 시간과 성능을 향상시킬 수 있다.

1. template 생성
  TrAX에서 template의 생성은 TransformerFactory와 Transformer 객체의 생성 과정 중간 단계에서 이루어진다.

  Templates template = transFactory.newTemplates(style);
  Transformer trans = template.newTransformer();

  template은 동일한 stylesheet를 이용해서 여러 번 문서 변환을 수행할 때 더 효과적이다.

2. parameter의 이용
  문서 변환 과정을 수행할 때 전달 가능한 값으로, 변환 결과에 영향을 미치게 된다.

  trans.setParameter("optionalChoice", "yes");

3. 다중 파일의 변환
  template과 parameter를 이용해서 여러 XML 파일을 효과적으로 변환하거나 하나의 XML 파일에 대해 여러 번 문서 변환을 수행할 수 있다.

  String outputFileName_opt = "transform_opt.html";
  String outputFileName_mand = "transform_mand.html";

  StreamResult result_opt = new StreamResult(outputFileName_opt);
  StreamResult result_mand = new StreamResult(outputFileName_mand);

  ...

  trans.setParameter("optionalChoice", "yes");
  trans.transform(source, result_opt);

  trans.setParameter("optionalChoice", "no");
  trans.transform(source, result_mand);

# 문서 변환과 SAX
  TrAX에서 SAX를 이용할 경우 추가적으로 고려해야 할 사항들
  - TrAX를 사용하기 전에 SAXSources와 SAXResults를 이용한다.
  - 문서 변환을 수행할 ContentsHandler를 작성하고, 이를 통해 입력 XML 문서를 파싱한다.
  - 문서 변환에 XMLFilters 객체를 사용할 수도 있다.

1. SAX 입력
  SAX 이벤트에 대한 소스를 생성하고 이를 문서 변환을 위한 입력으로 이용하기 위해 SAXSource 객체를 지정한다.

  XMLReader reader = XMLReaderFactory.createXMLReader();
  SAXSource source = new SAXSource(reader, new InputSource("inputFile.xml"));

  StreamResult result = new StreamResult("outputFile.xml");

  TransformerFactory transFactory = TransformerFactory.newInstance();
  Source style = transFactory.getAssociatedStylesheet(source, null, null, null);
  Transformer trans = transFactory.newTransformer(style);

  trans.transfor(source, result);

  입력 문서의 유효성 검증은 다음과 같이 가능하다.

  String featureId = "http://www.xml.org/sax/features/validation";
  reader.setFeature(featureId, true);

2. Transformer를 ContentsHandler로 이용
  Transformer를 Contentshandler로 명시적으로 선언

  StreamResult result = new StreamResult("outputFile.xml");

  TransformerFactory transFactory = TransformerFactory.newInstance();
  SAXTransformerFactory saxTransFactory = (SAXTransformerFactory)transFactory;

  TransformerHander trans = saxTransFactory.newTransformerHandler(style);
  trans.setResult(result);

  XMLReader reader = XMLReaderFactory.createXMLReader();

  reader.setContentHandler(trans);

3. SAX 출력
  문서 변환의 결과로 출력되는 SAX 스트림이 의미를 가지도록 하기 위해서는 이 SAX 스트림을 ContentsHandler에 전달해야 한다.

4. 연속된 문서 변환
 
  한 문서 변환 과정의 결과가 다른 문서 변환 과정의 입력으로 처리 되는 식의 연속된 처리 과정

  StreamSource style1 = new StreamSource("votes1.xsl");
  StreamSource style2 = new StreamSource("votes2.xsl");

  StreamResult result = new StreamResult("output.xml");

  TransformerFactory transFactory = TransformerFactory.newInstance();

  SAXTransformerFactory saxTransFactory = (SAXTransformerFactory)transFactory;

  TransformerHandler trans1 = saxTransFactory.newTransformerHandler(style1);
  TransformerHandler trans2 = saxTransFactory.newTransformerHandler(style2);

  trans1.setResult(new SAXResult(trans2));  // trans1에 대한 출력을 SAXResult로 trans2에 전달
  trans2.setResult(result);                 // trans2에 대한 출력을 result로 출력

  XMLReader reader = XMLReaderFactory.createXMLReader();
  reader.setContentHandler(trans1);
  reader.parse("xmlfile.xml");

5. SAX와 XMLFilter
  XMLFilter를 이용하여 연속된 문서 변환을 수행할 수도 있다.

  XMLFilter trans1 = saxTransFactory.newXMLFilter(style1);
  XMLFilter trans2 = saxTransFactory.newXMLFilter(style2)'

  TransformerHandler output = saxTransFactory.newTransformerHandler();
  output.setResult(result);

  trans1.setParent(reader);
  trans2.setParent(trans1);
  trans2.setContentHandler(output);

  trans2.parse("output.xml");

# stylesheet 문서 내에서의 프로그래밍

  stylesheet 문서 내에서 확장 함수나 element들을 생성할 수 있는 방법을 정의하고 있다.

1. 확장함수
  사용자 정의 함수를 이용하기 위해서는 새로운 namespace를 생성하여 XSLT 변환 엔진이 새로 정의된 함수를 인식할 수 있도록 해야 한다.

  <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                  xmlns:lxslt="http://xml.apache.org/xslt"
      xmlns:results="http://www.example.com/results"
      extension-element-prefixes="results"
      version="1.0">
  <lxslt:component prefix="results" functions="addVote, getResults">
 <lxslt:script lang="javascript">
      var sparkle, dregraal;

   sparkle = 0;
   dregraal = 0;

   function addVote(thisVote) {
     if( thisVote.equals("Sparkle") ) {
     sparkle++;
     } else {
       dregraal++;
     }
     return null;
   }

   function getResults() {
     return "Sparkle : " + sparkle + " Dregraal : " + dregraal;
   }
    </lxslt:script>
  </lxslt:component>

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

구조적 VS 객체지향적  (0) 2007.02.27
자바서비스넷의 기술자료 링크  (0) 2007.02.23
09. XSLT(eXtensible Stylesheet Language Transformations)  (0) 2007.02.20
08.XML Schema  (0) 2007.02.16
07.DTD(Document Type Definition)  (0) 2007.02.15
:
Posted by 뽀기

# XSLT (eXtensible Stylesheet Language Transformations)
  XSL(XML Stylesheet Language)
   : CSS의 기능과 유사하게 XML 문서에 대한 style을 정의하고 적용할 때 사용하는 언어
  XSLT
   : XSL 표준을 구성하는 일부, XML 데이터를 변경할 때 필요한 '규칙'을 정의할 목적으로 고안됨.
   : 주로 XML 데이터를 HTML 페이지로 변환하여 이를 브라우저에 출력하는데 이용

# XSL, XSLT, XSL-FO
  XSLT : 문서의 변환 규칙을 정의하기 위한 언어
  XSL-FO : XSL, 즉 XML을 위한 stylesheet 정의 언어에서 이용될 formatting 객체를 정의하는 언어. 문서가 어떻게 꾸며져야 하는지 지정하기 위해 사용.

#. XSLT의 기본 구조

1. stylesheet 문서
  XSLT 문서는 transform element를 root로 하며, XSL에 대한 namespace와 하나 이상의 template 정보를 포함한다.

  <?xml version="1.0"?>
  <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/">
    <html>
   <head><title>Thank you letter</title></head>
   <body>
   ...
   </body>
 </html>
  </xsl:template>
  </xsl:transform>

2. 값의 출력
  XSLT의 value-of element를 이용하여 프로세서를 통해 특정 정보 아이템을 출력할 수 있다.

# XPath의 개요

1. 자식과 후손 엘리먼트
  XPath는 XML 문서 내에 현재 방문중인 노드(context node)에서 이동하고자 하는 노드에 대한 위치 정보를 제공
  context node가 결정되면 다른 node로의 방문은 file system 이나 URL과 유사하다.

 <?xml version="1.0"?>
 <content>
  <events>
   <eventitem eventid="A335">
    <eventdate>6.20.3425</eventdate>
    <title>Making Friends With The Venusian Flu Virus</title>
    <description>Dr. Biff Mercury discusses his theory on coexisting with useful organism.</description>
   </eventitem>
   <eventitem eventid="B963" optional="no">
    <eventdate>6.21.3425</eventdate>
    <title>Putting the Manners in Bedside Manner</title>
    <description>Dr. Zingzowpowie, the famous xenoneurosurgen lectures on Bedside Manner and the benefits of using cold tentacles during a physical</description>
   </eventitem>
   <eventitem eventid="C934" optional="yes">
    <eventdate>6.25.3425</eventdate>
    <title>An evening of Fun</title>
    <description>This evening join us for the monthly "Identify that Food" contest.</description>
   </eventitem>
  </events>
  <news>
   <newsitem itemnum="1">
    <newsdate>6.18.3425</newsdate>
    <title>End of the line for the incumber?</title>
    <body>
     The Universal News Network is reporting that <person>His Magnificence The Supreme Leader For Life</person>
     announced today that he has decided not to be cloned for a 14th term.
    </body>
   </newsitem>
   <newsitem itemnum="2">
    <newsdate>6.19.3425</newsdate>
    <title>New Fall Lineup</title>
    <body>
     The Omega Channel has announced two new shows for its new fall lineup.
     <program>Who's Running the Galaxy?</program>
     features a team of government scientists who accidentally clone two Supreme Leaders.
     If you think you're confused, imagine what the first family must be going through.
     <program>Trading Species</program> follows two temas of aliens who trade species
     and have only 48 hours to adjust and fool their neighbors.
    </body>
   </newsitem>
  </news>
 </content>

  context node가 content node 라면
   - newsdate element로 이동하기 위한 XPath 표현식은 news/newsitem/newsdate 이다.
   - events/eventitem/eventdate와 같은 경우는 문서 내 모든 eventdate element를 지칭한다.
   - content//title 과 같은 경우는 eventitem element 또는 newsitem element의 자식 element인 title element 모두를 가리킨다.
  news node가 context node인 경우 newsdate element로 이동하기 위해서는 newsitem/newsdate 와 같이 표기할 수 있다.
  //title과 같은 경우는 root element의 모든 후손 element 중에서 title element를 가리킨다.

2. 문서의 root
  절대 경로를 지원한다.
  newsdate element는 /content/news/newsitem/newsdate 과 같이 표기할 수 있다.

  / 는 한 문서의 root 이며 content 는 이 문서의 root element 이다.

  content는 문서 root(/)의 자식 element(/content)로 표현된다.

3. attribute
  attribute를 element의 자식으로 취급하지 않는다.
  XPath에서의 attribute 표현은 @를 이용한다.

  news element가 context node일 경우 다음과 같이 표현할 수 있다.

  /content/events/eventitem@eventid
  /content//newsitem@newsid
  newsitem@newsid

4. 검색조건
  element들의 그룹에서 특정 기준을 만족하는 element만 추려낼 수 있는 필터
  XPath에서는 []를 이용하여 특정 조건을 기술할 수 있다.

  예)
  attribute 값이 C934인 eventid attribute를 가지는 eventitem element를 선택하는 경우
  /content/events/eventitem[@eventid='C934']

  [] 내의 텍스트는 검색 대상과 검색 조건을 타나내며, 검색 조건읜 괄호 내 오른쪽에 표기한다.

  이 표현식의 처리 결과는 element 목록을 반환한다.

  문서내에서 특정 element에 대한 정보의 존재 유무를 확인하려면 다음과 같이 사용한다.

  /content/events/eventitem[@eventid]

# template
  XSLT 문서에서 모든 변환 과정은 하나 이상으 template으로 정의, 실행된다.
  template은 입력 문서에서 변환할 부분을 선택하고 출력 형식을 정의한다.

1. template의 생성
 
  <?xsml version="1.0"?>
  <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:template match="/content/events/evenetitem">
    <h2>An event title</h2>
 <h3>(Date</h3>
 <p>An event description</p>
 <hr/>
  </xsl:template>
  <xsl:template match="/content/news">
  </xsl:template>
  </xsl:transform>

  match attribute는 template이 처리할 노드나 노드들을 지정하는데 이용된다.
  eventitem element를 방문할 때 마다 정보를 변환하여 출력한다.

2. template의 적용
  stylesheet에서는 하나의 template으로 문서를 변환하는 것보다 여러 개의 template으로 입력XML 문서의 정보들을 단계적으로 처리하는 것이 더 효과적이다.

 <xsl:template match="/">
  <xsl:apply-templates/>
 </xsl:template>

 <xsl:template match="/content/events/eventitem/title">
  <h2><xsl:value-of select="."/></h2>
 </xsl:template>

 <xsl:template match="/content/events/eventitem/eventdate">
  <h3>(<xsl:value-of select="." />)</h3>
 </xsl:template>

 <xsl:template match="/content/events/eventitem/description">
  <p><xsl:value-of select="."/></p>
  <hr/>
 </xsl:template>
  apply-templates element를 이용해서 stylesheet에 정의된 다른 template을 적용할 수 있다.

  아래와 같이 하면 각 element의 순서를 입력문서에 나타나는 순서로 맞출 수 있다.

 <xsl:template match="/content/events/eventitem">
  <xsl:apply-templates select="title"/>
  <xsl:apply-templates select="eventdate"/>
  <xsl:apply-templates select="description"/>
  <hr/>
 </xsl:template>

 <xsl:template match="title">
  <h2><xsl:value-of select="."/></h2>
 </xsl:template>
 <xsl:template match="eventdate">
  <h2><xsl:value-of select="."/></h2>
 </xsl:template>
 <xsl:template match="description">
  <h2><xsl:value-of select="."/></h2>
 </xsl:template>

3. 내장 template
  template 규칙이 정의되지 않은 영역에 대해 내부적으로 적용되는 template을 내장 template으로 정의한다.

# 컨텐츠의 생성

1. 동적 element
  element element를 이용하여 생성할 수 있다.

  <xsl:template match="title">
    <xsl:element name="h2">              --+
   <xsl:value-of select="."/>           +- <h2><xsl:value-of select="title"/></h2> 와 같은 표현
 </xsl:element>                       --+
  <xsl:template>

  =>

  <h2>Making Friends with... </h2>

2. 동적 attribute
 element element로 생성한 element에 attribute를 추가하기 위해서는 attribute element를 이용한다.

  <xsl:template match="title">
    <xsl:element name="h2">
      <xsl:element name="a">
        <xsl:attribute name="href">register.php?event=<xsl:value-of select="../@eventid"/></xsl:attribute>
        <xsl:value-of select="."/>
      </xsl:element>
    </xsl:element>
  </xsl:template>

  =>

  <h2><a href="register.php?event=A335">Making Friedns ...</a></h2>

3. XML에서 XML로의 변환
  XLST는 XML 문서를 다른 문서 구조를 가지는 XML 문서로 변환하기 위해 이용할 수 있다.

  <xsl:template match="/">
    <schedule>
   <xsl:apply-templates />
 </schedule>
  </xsl:template>

  <xsl:template match="content/events/eventitem">
    <xsl:element name="action">
   <xsl:attribute name="optinal"><xsl:value-of select="@optional"/></xsl:attribute>
   <title><xsl:value-of select="title"/></title>
 </xsl:element>
  </xsl:template>

  =>

  <!-- If an event is not explicitly marked as "optional", then it's mandatory -->

4. 주석문의 추가
  comment element를 이용한다.

  <xsl:comment>If an event is not explicitly marked as "optional", then it's mandatory</xsl:comment>

5. 처리 지시문
  XSLT를 이용해 문서 변환을 수행하는 application이 처리 지시문을 보려 할 경우, 이를 template에 직접 추가할 수는 없으나 명시적으로 생성할 수는 있다.

  <xsl:template match="content/events/eventitem">
    <xsl:processing-instruction name="updateSched">id="<xsl:value-of select="@eventid"/>"</xsl:processing-instruction>
 ...
  </xsl:template>

  =>

  <?updateSched id="A335'?>

6. 데이터의 정렬
  sort element를 제공

  <xsl:template match="/">
    <schedule>
   <xsl:comment>If an event is not explicitly marked as "optional", then it's mandatory</xsl:comment>
   <xsl:apply-templates select="content/events/eventitem">
     <xsl:sort select="eventdate" order="descending"/>
   </xsl:apply-templates>
 </schedule>
  </xsl:template>

7. 반복문의 생성
  for-each element를 이용

  <xsl:template match="/">
    <xsl:for-each select="eventitem">
   <xsl:apply-templates select="title"/>
 </xsl:for-each>
  </xsl:template>

8. copy-of와 value-of
  value-of : 해당 element의 값
  copy-of : element의 값 뿐만 아니라 element나 attribute를 포함한 node 집합의 전체 구조

  노드의 복사(eventitem element 단위로 출력 문서를 작성)
    <?xml version="1.0"?>
 <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:template match="content/events/eventitem">
     <xsl:copy-of select="."/>
   </xsl:template>
 </xsl:trasnform>

# 변수와 파라미터

1. named template
  template을 적용할 대상을 match attribute로 지정하지 않으며, template의 이름만 지정.
  이 template은 call-template element로 직접 적용한다.

  <xsl:template match="/content/events">
    <xsl:call-template name="eventTemplate"/>
  </xsl:template>

  <xsl:template name="eventTemplate">
    <xsl:for-each select="eventitem">
   <xsl:apply-templdate select="title"/>
   <xsl:apply-templdate select="eventdate"/>
   <xsl:apply-templdate select="description"/>
 </xsl:for-eachL
  </xsl:template>

  <xsl:template match="title">
  ...
  </xsl:template>
  ...

2. parameter
  parameter를 미리 정의하고 이를 나중에 참조할 수 있다.
  param element를 이용해 parameter를 생성한다.
  문서에서 parameter를 참조할 때 parameter의 이름 앞에 $ 기호를 붙인다.

  <xsl:param name="optionalChoice" select="'no'"/>

  <xsl:for-each select="eventitem[@optional=$optionalChoice]">
  ...
  </xsl:for-each>

3. named template and parameter
  template을 호출할 때 parameter를 설정할 수 있다.

  <xsl:call-template name="eventTemplate">
    <xsl:with-param name="isOptional"><xsl:value-of select="$optionalChoice"/></xsl:with-param>
  </xsl:call-template>
  <xsl:call-template name="eventTemplate">
    <xsl:with-param name="isOptional"><xsl:value-of select="$optionalChoice"/>x</xsl:with-param>
  </xsl:call-template>

  ...

  <xsl:template name="eventTemplate">
    <xsl:param name="isOptional" select="'no'"/>
 <xsl:for-each select="eventitem[@optiona=$isOptional]">
   <xsl:apply-templates select="title"/>
   ...
 </xsl:for-each>
  </xsl:template>
  </xsl:call-template>

4. 변수
  parameter와 다르게 사용된 이후에 새로운 값으로 설정이 가능하다.

  변수 정의의 문법
  1. select attribute를 이용해 변수 값을 직접 설정할 수 있다.
  2. variable element의 contents를 설정함으로써 변수 값을 설정할 수 있다.

  <xsl:variable name="optionalChoiceValue" select="$optionalChoice"/>
  <xsl:call-template name="eventTemplate">
    <xsl:with-param name="isOptional"><xsl:value-of select="$optionalChoiceValue"/></xsl:with-param>
  </xsl:call-template>

# 흐름제어
  XSLT는 변환 엔진이 어떤 template을 처리해야 하는지 명시할 수 있도록 흐름 제어 기능을 제공한다.

1. if-then element

if element는 명령어 치리를 위한 조건을 가질 수 있도록 test attribute를 갖는다.
  <xsl:element name="div">
    <xsl:if test="$isOptional='no'">
   <xsl:attribute name="style">color:red</xsl:attribute>
    </xsl:if>
 ...
  </xsl:element>

2. choose element
  if element를 이용하여 처리할 수 없는 else 문제 해결
  choose element는 잘 구성된 element들로 표현되는 분기 조건들을 담을 수 있는 container를 제공.
  하나 이상의 when element를 포함.
  when element는 if element와 유사한 동작 수행.
  otherwise element를 통해 when 문장들을 참으로 만족시키지 않는 다른 모든 조건들을 처리할 수 있도록 함.

  <xsl:call-template name="eventTemplate">
    <xsl:with-param name="isOptional">
   <xsl:value-of select="$optionalChoice"/></xsl:with-param>
  </xsl:call-template>

  <xsl:choose>
    <xsl:when test="$optionalChoice='yes'">
   <xsl:call-template name="eventTemplate">
     <xsl:with-param name"isOptional">no</xsl:with-param>
 </xsl:when>
    <xsl:when test="$optionalChoice='no'">
   <xsl:call-template name="eventTemplate">
     <xsl:with-param name"isOptional">yes</xsl:with-param>
 </xsl:when>
 <xsl:otherwise>
   <!-- If a yes or no value was not originally specified, assume it should have been no. That means the opposite is yes. -->
   <xsl:call-template name="eventTemplate">
     <xsl:with-param name="isOptional">yes</xsl:with-param>
   </xsl:call-template>
 </xsl:otherwise>

# 출력 모드의 설정
  mode attribute를 이용하여 어떤 template이 이용되어야 하는지 그리고 어떤 template이 처리되어야 하는지 지정할 수 있다.

  ...
  <xsl:apply-templates select="eventitem[$optional='no']" mode="no"/>
  ...

  <xsl:template match="eventitem" mode="yes'>
    <xsl:element name="div">
 ...
 </xsl:element>
  </xsl:template>

  ...

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

자바서비스넷의 기술자료 링크  (0) 2007.02.23
10. XML 문서의 변환과 응용  (0) 2007.02.22
08.XML Schema  (0) 2007.02.16
07.DTD(Document Type Definition)  (0) 2007.02.15
06. XML 문서에 대한 유효성 검증  (0) 2007.02.15
:
Posted by 뽀기
2007. 2. 16. 16:30

08.XML Schema 그거/Tech2007. 2. 16. 16:30

# XML Schema의 구조
  XML Schema는 그 자체가 XML 문서이며, XML과 동일한 문법을 이용한다.

1. 기본구조
  <schema> root element와 namespace 선언을 갖는다.

  <?xml version="1.0" encoding="EUC-KR"?>
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  </xs:schema>

2. system에 문서 정보의 제공

  스키마에 대한 정보를 문서화하는 표준화된 방법을 제공.
  스키마를 처리하는 application이 이 정보를 처리.

  <?xml version="1.0" encoding="EUC-KR"?>
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:annotation>
   <xs:documentation>
     이 문서는 그룹 목록에 대한 스키마를 설명한다.
   </xs:documentation>

   <xs:appinfo>
     <config xmlns="http://www.example.com/externalapp">
    <customertype>pop culture</customertype>
    <destination id="I43"/>
  </config>
   </xs:appinfo>
 </xs:annotation>
  </xs:schema>

3. 스키마 문서의 사용

  스키마 문서(XML문서에 대한 XML Schema가 정의되어 있는 문서) - 인스턴스 문서(XML 문서)

  <?xml version="1.0" encoding="EUC-KR"?>
  <collection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:noNamespaceSchemaLocation="collectibles.xsd">
  </collection>

# 단순 element

  XML Schema에서는 <element> element로 element를 정의.
  element에 data type을 지원할 수 있다.(현재 44개의 내장 data type 지원)

  <xs:element name="description" type="xs:string"/>
  <xs:element name="originDate" type="xs:date"/>
  <xs:element name="numOwners" type="xs:positiveInteger"/>

1. 내장 data type
  . 문자열 : string, normalizedString, token
  . 정수   : byte, unsignedByte, integer, positiveInteger, negativeInteger, nonNegativeInter, nonPositiveInteger, int, unsignedInt, long, unsignedLong, short, unsignedShort
  . 소수   : float, double
  . boolean : Boolean
  . 날짜/시간 : gMonth, gYear, gYearMonth, gDay, gMonthDay, duration, time, dateTime, date
  . binary    : base64Binary, hexBinary
  . DTD 호환성 : attribute만 사용 가능. ID, IDREF, IDREFS, ENTITY, ENTITIES, NOTATION, NMTOKEN, NMTOKENS
  . namespace 연관 : QName, NCName
  . 그 외 : anyURI, lang, Name

2. 고정값과 기본값
 
  <xs:element name="obtainable" type="xs:string" fixed="yes"/>
  <xs:element name="originalOwner" type="xs:string" default="unknown"/>

  변환과정
    <obtainable/> => <obtainable>yes</obtainable>
    <originalOwner/> => <originalOwner>unknown</originalOwner>

  일반 entity를 대체하여 이용되는 경우
    <xs:element name="copy" fixed="@"/>

    <rights>Copyright <copy/>2003</rights>


# 복합 element
  element내에 element가 포함되는 경우를 복합 타입으로 간주.

1. 자식 element의 정의

  <?xml version="1.0" encoding="EUC-KR"?>
  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="obtainable" type="xs:string" fixed="yes"/>
    <xs:element name="originalOwner" type="xs:string" default="unknown"/>

   <xs:element name="collection">
     <xs:complexType>
    <xs:sequence>   <- element들이 순서대로 나타나야 한다. <xs:all> 로 하면 임의의 순서로 나타난다.
      <xs:element name="toys" type="xs:string"/>
      <xs:element name="furniture" type="xs:string"/>
      <xs:element name="pottery" type="xs:string"/>
      <xs:element name="autographs" type="xs:string"/>
      <xs:element name="advertising" type="xs:string"/>
    </xs:sequence>
  </xs:complexType>
   </xs:element>
  </xs:schema>

  <?xml version="1.0" encoding="EUC-KR"?>
  <collection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:noNamespaceSchemaLocation="collectibles.xsd">

    <toys></toys>
 <furniture></furniture>
 <pottery></pottery>
 <autographs></autographs>
 <advertising></advertising>
  </collection>

  자식 element의 선택
    <?xml version="1.0" encoding="EUC-KR"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <xs:element name="obtainable" type="xs:string" fixed="yes"/>
      <xs:element name="originalOwner" type="xs:string" default="unknown"/>

        <xs:element name="collection">
          <xs:complexType>
            <xs:choice>    <- DTD에서의 '|'와 같은 기능
              <xs:element name="toys" type="xs:string"/>
              <xs:element name="furniture" type="xs:string"/>
              <xs:element name="pottery" type="xs:string"/>
              <xs:element name="autographs" type="xs:string"/>
              <xs:element name="advertising" type="xs:string"/>
            </xs:choice>
          </xs:complexType>
        </xs:element>
    </xs:schema>

2. 출연 횟수의 제어
  minOccurs와 maxOccurs attribute를 사용하여 특정 element의 출현 횟수를 제어할 수 있다.
  sequence, choice, all element와 minOccurs, maxOccurs attribute를 적절히 취합하여 구성가능

  <xs:element name="previousOwner" type="xs:string" minOccurs="0" maxOccurs="5"/>

  <xs:element name="collection">
    ...
    <xs:choice minOccurs="1" maxOccurs="unbounded">
    </xs:choice>
  </xs:element>

3. 혼합 contents
  complexType element에 mixed attribute를 사용.

  <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="collection">
    <xs:complexType mixed="false">
   <xs:choice minOccurs="1" maxOccurs="unbounded">
     <xs:element name="toys">
    <xs:complexType>
      <xs:sequence>
     <xs:element name="previousOwner" type="xs:string" minOccurs="0" maxOccurs="5"/>
     <xs:element name="description"
       <xs:complexType mixed="true">
      <xs:choice maxOccurs="unbounded">
        <xs:element name="condition" type="xs:string"/>
     <xs:element name="brand" type="xs:string"/>
     <xs:element name="tradeName" type="xs:string"/>
      </xs:choice>
    </xs:complexType>
     <xs:element>
   </xs:sequence>
    </xs:complexType>
  </xs:element>
      </xs:choice>
 </xs:complexType>
  </xs:element>
  </xs:schema>

4. anyType
  DTD의 ANY 타입 element와 동일한 기능을 수행하며, anyType으로 선언된 element는 contents model에 어떤 text 값도 가질 수 있다.

  <xs:element name="condition" type="xs:string"/>
  <xs:element name="brand" type="xs:string"/>
  <xs:element name="tradeName" type="xs:string"/>
  <xs:element name="collection">
    <xs:element name="description" type="xs:anyType"/>
  </xs:element>

  description이 anyType으로 설정되어있기 때문에
  description element 외부에 선언되어 있는 condition, brand, tradeName element를 자식 element로 가질 수 있다.

# 미리 정의된 element 들의 참조

  element에 대한 참조

  <xs:element name="condition" type="xs:string"/>

  ref attribute를 이용해서 참조
  <xs:element name="item">
    <xs:complexType>
   <xs:sequence>
     <xs:element ref="condition" minOccurs="0" maxOccurs="5"/>
   </xs:sequence>
 </xs:complexType>
  </xs:element>

  참조되는 element들의 fixed, default attribute 등은 element 선언 내에서 정의되며,
  minOccurs, maxOccurs attribute는 element를 참조하는 위치에서 정의된다.
  전역으로 정의된 element를 참조 형식으로 이용하는 경우 element 선언의 재사용이 가능하다.

1. 범위의 설정
  동일한 이름을 갖는 element는 상위 element의 범위 내에서만 유효하다.

  전역 선언된 item element와 pottery element 내부에 선언된 item element가 있을 경우
  pottery element 내부에 선언된 item element에 material 이라는 element를 하나 추가할 경우
  material element를 갖는 item element는 pottery element 내부에서만 유효하다.

2. element group의 설정
 
  <xs:group name="itemCommon">
    <xs:sequence>
   <xs:element ref="previousOwner" minOccurs="0" maxOccurs="5"/>
   <xs:element ref="description"/>
   <xs:element ref="originDate"/>
   <xs:element ref="numOwners"/>
   <xs:element ref="obtainable"/>
   <xs:element ref="originalOwner"/>
 </xs:sequence>
  </xs:group>

  <xs:element name="item">
    <xs:complexType>
   <xs:sequence>
     <xs:group ref="itemCommon"/>
   </xs:sequence>
 </xs:complexType>
  </xs:element>
  ....
  <xs:element name="pottery">
    <xs:complexType>
   <xs:sequence>
     <xs:element name="item" minOccurs="0" maxOccurs="unbounded">
    <xs:complexType>
      <xs:sequence>
     <xs:group ref="itemCommon"/>
     <xs:element name="material" type="xs:string"/>
   </xs:sequence>
    </xs:complexType>
  </xs:element>
   </xs:sequence>
 </xs:complexType>
  </xs:element>

# attribute의 정의

  attribute element를 통해 선언

  <xs:element name="item">
    <xs:complexType>
   <xs:sequence>
     <xs:group ref="itemCommon"/>
   </xs:sequence>
   <xs:attribute name="itemid" type="xs:integer"/>
   <xs:attribute name="keeper" type="xs:integer"/>
   <xs:attribute name="demand" type="xs:integer"/>
   <xs:attribute name="legal" type="xs:integer"/>
 </xs:complexType>
  </xs:element>

  XML schema의 모든 내장 data type을 이용할 수 있다.

1. attribute의 속성 결정

  DTD        : #REQUIRED #IMPLIED #FIXED
  XML schema : use, default, fixed

  <xs:attribute name="itemid" type="xs:integer" use="required"/>
  <xs:attribute name="keeper" type="xs:string" default="yes"/>
  <xs:attribute name="demand" type="xs:string" use="optional"/>
  <xs:attribute name="legal" type="xs:string" fixed="yes"/>

  use, default, fixed는 attribute 선언에서 함께 사용될 수 없다.

2. attribute의 전역 선언과 attribute group

  <xs:attribute name="itemid" type="xs:integer"/>
  <xs:attribute name="keeper" type="xs:string"/>
  <xs:attribute name="demand" type="xs:string"/>
  <xs:attribute name="legal" type="xs:string"/>

  ref를 이용하여 참조한다.
  <xs:attribute ref="itemid" use="required"/>

  attribute의 group의 선언에서 group에 포함될 attribute들은 미리 선언되어 있어야 한다.
  <xs:attribute name="itemid" type="xs:integer"/>
  <xs:attribute name="keeper" type="xs:string"/>
  <xs:attribute name="demand" type="xs:string"/>
  <xs:attribute name="legal" type="xs:string"/>

  <xs:attributeGroup name="itemAtts">
    <xs:attribute ref="itemid" use="required"/>
    <xs:attribute ref="keeper" default="yes"/>
    <xs:attribute ref="demand" use="optional"/>
    <xs:attribute ref="legal" fixed="yes"/>
  </xs:attributeGroup>

  attribute group의 사용
  <xs:element name="item">
    <xs:complexType>
   <xs:sequence>
     <xs:group ref="itemCommon"/>
   </xs:sequence>
      <xs:attributeGroup ref="itemAtts"/>
 </xs:complexType>
  </xs:element>

# 새로운 타입의 생성
  내장 data type 외에 새로운 type을 사용자가 정의할 수 있다.
  범위 값 등 단순한 것부터 element와 attribute 들을 포함하는 계층 구조 같은 복잡한 type도 가능.

1. 이름이 부여된 type
  복합 type을 선언하고, 이 선언에 대해 이름을 부여

  <xs:complexType name="itemType">
    <xs:sequence>
   <xs:group ref="itemCommon"/>
 </xs:sequence>
 <xs:attributeGroup ref="itemAtts"/>
  </xs:complexType>

  ...

  <xs:element name="item" type="itemType" minOccurs="0" maxOccurs="unbounded"/>

2. 제약 사항의 부여
  내장 data type에 여러가지 제약 사항을 추가함으로써 새로운 type을 생성할 수 있다.

  <xs:simpleType name="USCurrency">
    <xs:restriction base="xs:decimal>
   <xs:fractionDigits value="2"/>
 </xs:restriction>
  </xs:simpleType

  <xs:element name="originalPrice" type="USCurrency"/>

  XML schema에서 제공하는 facet
  minInclusive     : 수의 최소값. 이상
  minExclusive     : 초과해야 하는 최소값. 초과
  maxInclusive     : 수의 최대값
  maxExclusive     : 미만이어야 하는 최대값
  totalDigits      : 소수점 앞,뒷자리를 포함한 수의 전체 자릿수 지정
  fractionDigits   : 소수점 뒷자리 수 지정
  length           : 값의 길이 지정
  minLength        : 문자형 데이터의 최소 길이
  maxLength        : 문자형 데이터의 최대 길이
  pattern          : 문자열 정보에 대한 정규 표현식
  enumeration      : 나열형 데이터에 대한 표기
  whiteSpace       : line feed, tab, carriage return 같은 특수 문자 처리. preserve(그대로), replace(한 개의 공백으로 대체), collapse(여러 개의 공백으로 대체)

  - 나열형 타입
    element와 attribute에 대한 선택을 제한

    <xs:attribute name="demand">
      <xs:simpleType>
        <xs:restriction base="xs:string">
          <xs:enumeration value="low"/>
          <xs:enumeration value="medium"/>
          <xs:enumeration value="high"/>
          <xs:enumeration value="money is no object"/>
        </xs:restriction>
      </xs:simpleType>
    </xs:attribute>

    demand attribute의 값은 low, medium, high, money is no object 중 하나만 선택되어야 한다.

  - List 타입
    공백으로 구분되는 여러 개의 값을 포함할 수 있다.

 <xs:simpleType name="possibleOutlets">
   <xs:restriction base="xs:string">
     <xs:enumeration value="oBoy"/>
     <xs:enumeration value="YoHoo!"/>
     <xs:enumeration value="ConJunction"/>
     <xs:enumeration value="Anazone"/>
   </xs:restriction>
 </xs:simpleType>

 <xs:simpleType name="outletList">
   <xs:List itemType="possibleOutlets"/>
 </xs:simpleType>

 <xs:simpleType name="outlets">
   <xs:restriction base="outletList">
     <xs:maxLength value="3"/>
      </xs:restriction>
 </xs:simpleType>


 <item itemid="1">
   ....
   <outlets>oBoy Yoohoo!</outlets>
 </item>

3. 확장을 통해 단순 타입에 attribute 추가
 
  <xs:element name="originalOwner">
    <xs:complexType>                                            <- element를 갖고 있기 때문에 복합타입으로 contents model 선언
   <xs:simpleContent>                                        <- 자식 element 없이 text 정보만을 가는 단순 컨텐츠만 취한다
     <xs:extension base="xs:string">
    <xs:attribute name="confirmed" default="no"/>
  </xs:extension>
   </xs:simpleContent>
 </xs:complexType>
  </xs:element>

# custom type 의 유도
  custom type의 확장

  <xs:complexType name="itemType">
    <xs:sequence>
 ...
    </xs:sequence>
  </xs:complexType>

  <xs:complexType name="potteryItemType">
    <xs:complexContent>
   <xs:extension base="itemType">                           <- itemType을 상속
     <xs:sequence>
    <xs:element name="material" type="xs:string"/>       <- element 하나 추가
  </xs:sequence>
      </xs:extension>
 </xs:complexContent>
  </xs:complexType>

  ...

  <xs:element name="item" type="potteryItemType" minOccurs="0" maxOccurs="unbounded"/>

  ...

1. 제약을 통한 타입의 유도

  복합 타입에 대한 제약 사항의 부여
  <xs:complexType name="advertisingItemType">
    <xs:complexContent>
   <xs:restriction base="itemType">
     <xs:sequence>
    <xs:element href="previousOwner" minOccurs="0" maxOccurs="unbounded"/>
  </xs:sequence>
   </xs:restriction>
 </xs:complexContent>
  </xs:complexType>

  ...

  <xs:element name="item" type="advertisingItemType" minOccurs="0" maxOccurs="unbounded"/>

  ...


  제약과 확장
  <xs:complexType name="autographRestrictType">
    <xs:complexContent>
   <xs:restriction base="itemType">
     <xs:sequence>
    <xs:element ref="previousOwner" minOccurs="5" maxOccurs="5"/>
    ...
    <xs:element name="lastPrice" type="USCurrency"/>
  </xs:sequence>
   </xs:restriction>
 </xs:complexContent>
  </xs:complextType>

  <xs:complexType name="autographItemType">
    <xs:complexContent>
   <xs:extension base="autographRestrictType">                <- autographRestrictType을 상속 받음
     <xs:sequence>
    <xs:element name="description" type="xs:string"/>      <- description, personFirst element 추가
    <xs:element name="personFirst" type="xs:string"/>
  </xs:sequence>
   </xs:extension>
 </xs:complexContent>
  </xs:complexType>

  원래 있는 element를 재정의 하기 xs:restriction
  원래 있는 element에 element를 추가하기 위해서는 xs:extension 사용


# 데이터 무결성

1. 유일 키의 지원
  XML schema는 데어터 무결성을 지원한다.

  <xs:unique name="itemIdKey">
    <xs:selector xpath=".//item"/>
 <xs:field xpath="@itemid"/>
  </xs:unique>

2. key 와 keyref
  DB의 foreign key 역할
  foreign key : 한 relation에 대한 primary key로, 반드시 나타나야 하는 값이면서 다른 relation에서 이를 참조하는 키 값

  <xs:element name="onSale">
    <xs:complexType>
   <xs:sequence>
     <xs:element name="itemForSale" minOccurs="0" maxOccurs="unbounded">
    <xs:complexType>
      <xs:sequence>
     <xs:element name="outlet" type="outlets"/>
     <xs:element name="itemid" type="xs:integer"/>
   </xs:sequence>
    </xs:complexType>
    <xs:keyref name="onSaleItems" refer="existingItems">
      <xs:selector xpath="."/>
   <xs:field xpath="itemid"/>
       </xs:keyref>
  </xs:element>
   </xs:sequence>
 </xs:complexType>
  </xs:element>
  </xs:unique>

  <xs:key name="existingItems">
    <xs:selector xpath=".//item"/>
 <xs:field xpath="@itemid"/>
  </xs:key>

# namespace의 지원

1. noNamespaceSchemaLocation
  namespace 접어를 이용하지 않으려 할 경우

  <collection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:noNamespaceSchemaLocation="collectibles.xsd">

2. targetnamespace
  스키마 문서에서 정의하는 element가 특정 namespace에 속해야 할 필요가 있을 경우

  <schema xmlns="http://www.w3.org/2001/XMLSchema"
          xmlns:col="http://www.example.com/collection"
    targetNamespace="http://www.example.com/collection"
    elementFormDefault="qualified"
    attributeFormDefault="qualified"
  >

3. 다중 namespace

  다른 namespace에 속하는 element 정의의 이용
  <?xml version="1.0" encoding="EUC-KR"?>
  <schema xmlns="http://www.w3.org/2001/XMLSchema"
         xmlns:col="http://www.example.com/collection"
   xmlns:spec="http://www.example.com/spec"
   targetNamespace="http://www.example.com/collection"
   elementFormDefault="qualified"
   attributeFormDefault="qualified"
  >
  ...
  <complexType name="itemType">
    <sequence>
   <element ref="col:previousOwner" minOccurs="0" maxOccurs="5"/>
   <element ref="spec:specifications" minOccurs="0"/>
    </sequence>
  </complexTyhpe>
  ...

  다중 namespace의 참조
  <?xml version="1.0" encoding="EUC-KR"?>
  <c:collection xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                xmlns:c="http://www.example.com/collection"
    xmlns:s="http://www.example.com/spec"
    xsi:schemaLocation="http://www.example.com/collection collectibles.xsd
                        http://www.example.com/spec specs.xsd">
  <c:toys>
    <c:item c:itemid="1" c:demand="money is no object">
   <c:previousOwner>John Sorhed</c:previousOwner>
   <c:description>
     This piece is a genuine wooden <c:brand>Silhaven</c:brand>
  .....
   </c:description>
   <s:sepcifications>The specifications are...</s:specification>
   <c:originDate>1940</c:originDate>
 </c:item>
  </ctoys>


:
Posted by 뽀기
2007. 2. 15. 19:13

07.DTD(Document Type Definition) 그거/Tech2007. 2. 15. 19:13

# DTD의 유형
  DTD는 XML 문서의 문서 구조를 정의하고, 해당 문서들이 정의된 문서 구조를 지키도록 하는데 이용된다.

1. 외부 DTD
  외부 문서에 XML 문서의 모든 정의를 가지고 있는 형식

  - 간단한 DTD 정의의 예

    <!ELEMENT orchestra (instruments)>
    <!ELEMENT instruments (woodwind)>
    <!ELEMENT woodwind (#PCDATA)>

  - 외부 DTD 사용의 예
    <!DOCTYPE orchestra SYSTEM "orchestra.dtd">

  - DOCTYPE 선언부
    <!DOCTYPE : 현재부터 > 기호 이전까지 문서 형식의 선언을 위한 영역임을 표시
 orchestra : 이 XML 문서에서의 root element 이름. XML 문서내의 다른 element로 변경 가능

  - SYSTEM 식별자
    해당 DTD 문서가 시스템의 어디에 위치하는지 알리기 위해서 사용

  - PUBLIC 식별자
    DTD 파일의 위치를 표시하는 것이 아니라 공식정인 이름을 지정하는데 사용

 XHTML 문서에 대한 DTD PUBLIC 식별자의 이름
   -//W3C//DTD XHTML 1.0 Transitional//EN
 
 문서가 변경되거나 이동될 때, 문서 작성자가 DTD에 대한 위치 경로를 신경쓰지 않도록 함으로써 더 쉽게 관리할 수 있도록 함

 PUBLIC 식별자를 인식하지 못하는 XML 프로세서를 위해 PUBLIC, SYSTEM 둘 다 표시하는 것이 일반적

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitinal//EN"
                       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-trasitional.dtd">

    {표준지시자}//{조직 이름}//{DTD 이름}//{언어}

 표준지시자 : 이 문서가 표준 기구에서 승인되었는지 여부(표준이면 +, 아니면 -)
 조직 이름  : 이 DTD의 생성과 유지에 대한 책임이 있는 조직의 이름
 DTD 이름   : DTD의 이름
 언어       : 이 문서가 어떤 문서로 작성되었는지 ISO 639 언어 코드값으로 표기

2. 내부 DTD
  DTD 정보는 [] 안에 위치한다.
  내부 DTD는 standalone 문서를 작성하기 위해 사용하며, 이는 XML 선언부에서 standalone="yes"로 선언한다.
  XML 선언부에 standalone에 대한 언급이 없으면 기본으로 standalone="no" 이다.


# element와 contents model의 생성

  element 선언문의 구조
  <!ELEMENT {이름} ({content smodel})>

1. 컨텐츠 변경자
  element의 출현 빈도 명시

  ? : 선택적인 element. 나타나지 않을 수도 있으며, 나타나면 한 번만 나타남
  + : 반드시 나타나야 하는 element. 한 번 이상
  * : 반복하여 나타나는 element. 0 번 이상

  <!ELEMENT orchestra (performance, instruments)>
  <!ELEMENT performance (piece+)>                       : 하나 이상의 piece element를 갖는다.
  <!ELEMENT piece (#PCDATA)>
  <!ELEMENT instruments (violin*, glockenspiel?)>       : violin은 한 번도 안나타나거나 여러번 나타나고, glockenspiel은 없거나 한 번만 나타남
  <!ELEMENT violin (#PCDATA)>
  <!ELEMENT glockenspiel (#PCDATA)>

2. element 선택자
  | : A or B

  <!ELEMENT orchestra (performance, instruments)>
  <!ELEMENT performance (piece+ | improv)>              : 한 개의 improv element나 한 개 이상의 piece element 중 하나만 선택
  <!ELEMENT piece (#PCDATA)>
  <!ELEMENT improv (#PCDATA)>

  <!ELEMENT instruments (violin*, glockenspiel?) | (piano?, clarinet+)>       : instrumenets element는 violin, glockenspiel element를 갖거나 piano, clarinet element의 조합을 갖게 된다.
  <!ELEMENT violin (#PCDATA)>
  <!ELEMENT glockenspiel (#PCDATA)>
  <!ELEMENT piano (#PCDATA)>
  <!ELEMENT clarinet (#PCDATA)>

  DTD가 가지는 한계
    XML 문서의 작성자가 컨텐츠 모델 변경자와 OR 연산자를 통해 임의의 순서로 element가 나타나게 할 수 있으나 element의 출현 횟수를 제어할 수 없다.

3. 혼합 컨텐츠
  element가 자식 element와 text contets를 모두 갖는 경우

  <description>
    this rehearsal will showcase <violin>Joel Borgnine</violin>L and his brilliant improvisation, <improv>Jazz on the Shore</improt>.
  </description>
 
  <!ELEMENT description ( #PCDATA | violin | improv | piece )*>

4. ANY element
  한 element가 DTD 내에 정의되어 있는 다른 어떠한 element들도 포함할 수 있는 기능을 제공

  <!ELEMENT description ANY>

  description element는 DTD 내에 정의되어 있는 다른 어떠한 element도 포함할 수 있다.

5. EMPTY element
  element의 contents model이 아무런 정보를 갖지고 있지 않은 경우
  예)<img src="../test.gif"/>

  <!ELEMENT intermission EMPTY>

  <intermission/> == <intermission></intermission>

  <intermission/> != <intermission> </intermission>
  intermission의 contents model에 공백 문자가 삽입되므로 같지 않다.


# attribute의 정의

  attribute list의 형식
  <!ATTLIST {element 이름} {attribute 이름} {타입} {기본값} {옵션}>

1. attribute의 기본값

  intermission element의 생략 가능한 setup attribute, length attribute
  <!ATTLIST intermission setup CDATA #IMPLIED
                         length CDATA #IMPLIED>

  intermission element에서 꼭 있어야 하는 setup attribute, 생략가능한 length attribute
  <!ATTLIST intermission setup CDATA "full" #REQUIRED
                         length CDATA #IMPLIED>

  intermission element에서 생략가능한 setup attribute, 생략가능하지만 기본값은 "15 minutes"로 고정되서 바꿀 수 없는 length attribute
  <!ATTLIST intermission setup CDATA "full"
                         length CDATA #FIXED "15 minutes">

2. 나열형 attribute
  DTD에서는 attribute에 대한 고정값을 명시할 수 있을 뿐만 아니라 이용 가능한 값의 집합을 나열할 수 있다.

  setup attribute에 대해서 기본값은 full, partial, minimal 중에 하나를 가질 수 있으며, 지정하지 않을 경우는 full을 값으로 설정
  <!ATTLIST intermission setup (full | partial | minimal) "full"
                         length CDATA #FIXED "15 minutes">

 
  <!ATTLIST intermission setup (full | partial | minimal) "full"
                         length CDATA #FIXED "15 minutes">
  <!ATTLIST piano type (accoustic | electronic) #IMPLIED>
  <!ATTLIST violin seat (first | second | other) #REQUIRED>

3. ID, IDREF 타입
  XML DTD에서는 DB의 기본키/외래키 기능을 지원하기 위해 ID, IDREF attribute를 정의해 놓고 있다.

  piece element에 대해서 IDREF 타입으로 pid attribute를 꼭 사용하도록 정의
  <!ATTLIST piece pid IDREF #REQUIRED>

  improv element에 대해서 IDREF 타입으로 iid attribute를 꼭 사용하도록 정의
  <!ATTLIST improv iid IDREF #REQUIRED>

  concertpiece element에 대해서 ID 타입으로 pieceid attribute를 꼭 사용하도록 정의
  <!ATTLIST concertpiece pieceid ID #REQUIRED>

  제약조건
    ID attribute의 값은 숫자로 시작할 수 없다.
                     구두점이나 공백문자를 포함할 수 없으며,
      이 값은 문서 내에서 유일해야 한다.
    IDREF attribute의 값은 문서 내에서 유일하지 않아도 무방하다.
                        문서 내에 존재하는 ID attribute의 값과 일치해야 한다.

    IDREF 의 값은 ID의 값과 같아야 한다.

 <piece pid="_1"/>
 <piece pid="_2"/>        <-- "_2"라는 ID 값이 없기 때문에 오류 발생
 <concertpieces>
   <concertpiece pieceid="_1">test</concertpiece>
 </concertpieces>

  IDREFS 타입 : attribute list의 선언에서 사용될 수 있으며, 공백문자로 구분되는 여러 개의 IDREF 값을 취급한다.
 
  <!ATTLIST piece pid IDREFS #REQUIRED>

  <performance>
    <piece pid="_1 _3"/>
  </performance>

  IDREFS 의 각 값은 문서 내에 존재하는 ID의 값이어야 한다.

4. NMTOKEN 타입
  ID 타입처럼 공백문자를 포함할 수 없으나 ID와는 달리 숫자로 시작할 수 있다.

  <!ATTLIST concertpiece pieceid ID #REQUIRED
                         genre NMTOKENS #IMPLIED>

  <concertpiece pieceid="_1" genre="jazz modern">Jazz on the Shore</concertpiece>

  IDREF 타입과는 달리 문서 내의 다른 구성 요소나 attribute 들을 참조하지 않는다.

# 일반 entity
  entity : XML 문서에서 다른 contents에 대한 참조를 나타내며,
           이를 문서 내에서 이용하기 위해서는 entity 이름의 앞과 뒤에 &와 ;를 붙여 호출한다.

  <p>&quot;To levitate a human being would take a magnet....&quot;</p>

1. custom entity
  문서 내에서 빈번하게 출현하는 data를 간략화ㅗ 할 수 있다.

  <!DOCTYPE orchestra SYSTEM "orchestra.dtd" [
    <!ENTITY callwarning "Please arrive prepared to play!">
    ]>

  <description>
    &callwarning;
    This rehearsal will showcase ....
  </description>

  parsed entity
  일반적인 text 정보

2. 이름 entity와 산술형 entity

  산술형 entity
  <!DOCTYPE orchestra SYSTEM "orchestra.dtd" [
    <!ENTITY flat "&#9837;">
  ]>

  <description>>
    This rehearsal will showcase... improvisation in B&flat;,....
  </description>

3. 외부 entity
  파일과 같은 외부 자원들을 참조하는 entity

  parsed entity
    일반 entity의 생성 방법과 비슷하나 특정 문자를 참조하는 대신 SYSTEM이나 PUBLIC 식별자를 이용한다.

 <!DOCTYPE orchestra SYSTEM "orchestra.dtd" [
   <!ENTITY flat "&#9837;">
   <!ENTITY concertpieces SYSTEM "musicalnumbers.xml">
 ]>

 </orchestra>
   <instruments>
     <violin seat="first">...</violin>
   </instruments>
   &concertpieces;
 </orchestra>

 일반 entity는 문서 내에서 정의되기 때문에 XML 문서의 파싱 과정에서 이 entity들이 text 정보로 대체되면서 XML 문서의 잘 구성됨 조건을 위배할 수 있다.
 XML 문서가 유효성 검사를 수행하지 않는 XML parser를 이용한다면, 이 parser는 외부 문서에 대한 유효성 검사를 수행하지 않음으로써 문제를 발생시킬 수 있다.

  unparsed entity
    image 파일과 같은 바이너리 데이터를 XML 문서에서 참조할 경우, 이 파일의 내용 정보를 XML 문법으로 파싱하지 못하도록 하기 위해 이용
 notation을 이용하여 해당 파일의 타입을 정의하고 외부 entity 선언으로 이 notation에 대한 참조를 설정한다.

 <!DOCTYPE orchestra SYSTEM "orchestra.dtd" [
   ...
   <!ENTITY concertpieces SYSTEM "musicalnumbers.xml">
   <!NOTATION gif SYSTEM "c:\winnt\system32\mspaint.exe">
   <!ENTITY logo SYSTEM "logo.gif" NDATA gif>

   <!ENTITY violinimg SYSTEM "violing.gif" NDATA gif>
   <!ENTITY firstseatimg SYSTEM "firstseat.gif" NDATA gif>
   <!ENTITY glockenspielimg SYSSTEM "glockenspiel.gif" NDATA gif>

   <!ATTLIST violin graphics ENTITIES #IMPLIED>
   <!ATTLIST glockenspiel graphics ENTITY #IMPLIED>

 ]>

 ...
   <violin seat="first" graphics="violinimg firstseatimg">Joel Borgnine</violin>
   <glockenspiel graphics="glockenspielimg">Marie Andrassy</glockenspiel>
 ...

 entity를 이용할 경우 entity의 호출은 &와 ;를 앞뒤에 붙이지 않는다.


# 파라미터 엔티티
  DTD에서 사용되는 entity. % 기호화 하나의 공백이 정의할 때 함께 추가된다.
  일반 attribute나 element group 처럼 미리 정의된 DTD 정의의 일부를 다시 DTD에서 여러 번 이용해야 할 경우

  <!DOCTYPE orchestra SYSTEM "orchestra.dtd" [
    <!ENTITY % flatEnt "<!ENTITY flat &#34;&#x266F;&#24;>">
    %flatEnt;

    <!ENTITY sharp "&#x266F;">
    <!ENTITY natural "&#x266E;">
    ...
  ]>

  <!ENTITY % seatAtt "first | second | other">

  <!ATTLIST violin seat (%seatAtt;) #REQUIRED>
  <!ELEMENT concertpieces (concertpiece*)>

1. DTD 정의의 취사 선택
 
  DTD에서의 조건 절
  <![INCLUDE[
    <!ELEMENT instruments (piano?, clarinet+)>
  ]]>
  <![IGNORE[
    <!ELEMENT instruments (violin*, glockenspiel?)>
  ]]>

  조건절과 parameter entity를 사용하여 아래와 같이 변경 가능하다

  <!ENTITY % woodwind "INCLUDE">
  <!ENTITY % string "IGNORE">

  <!ELEMENT orchestra (performance, description, instruments, concertpieces)>
  ...
  <!ELEMENT description ANY>

  <![%woodwind;[
    <!ELEMENT instruments (piano?, clarinet+)>
  ]]>
  <![%string;[
    <!ELEMENT instruments (violin*, glockenspiel?)>
  ]]>

  parameterized DTD

  <!ENTITY % woodwind "INCLUDE">
  <!ENTITY % string "IGNORE">
  <!ENTITY % custom "IGNORE">
  <!ENTITY % customSet "">

  ...

  <![%woodwid;[
    <!ELEMENT instruments (piano?, clarinet+)>           // INCLUDE
  ]]>
  <![%string;[
    <!ELEMENT instruments (viloin*, glockenspiel?)>      // IGNORE
  ]]>
  <![%custom;[
    <!ELEMENT instruments (%customSet;)>                 // IGNORE
  ]]>

  parameter entity의 이용

  <!ENTITY % woodwind "IGNORE">
  <!ENTITY % string "IGNORE">
  <!ENTITY % custom  "INCLUDE">                          // INCLUDE 됐기 때문에 위에서 <!ELEMENT instruments (%customSet;)>을 사용함
  <!ENTITY % customSet "piano, glockenspiel">

  ...

    <instruments>                                                     // <!ELEMENT instruments (%customSet;)>을 사용하는데 %customSet; 이 piano, glockenpiel 이기 때문에
   <piano>xxx</piano>                                              // instruments element는 piano, glockenpiel element를 포함한다
   <glockenspiel graphics="glockenspielimg">xxxa</glockenspiel>
 </instruments>
  ...


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

09. XSLT(eXtensible Stylesheet Language Transformations)  (0) 2007.02.20
08.XML Schema  (0) 2007.02.16
06. XML 문서에 대한 유효성 검증  (0) 2007.02.15
05. XML 스트림 (SAX)  (0) 2007.02.14
04. DOM의 활용(고급편)  (0) 2007.02.14
:
Posted by 뽀기
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 뽀기