반응형
출처: http://kr.blog.yahoo.com/kwon37xi/folder/3381246.html


  • JAXP는 새로운 기능을 제공하는 것이 아니라 기존의 SAX, DOM 파서들을 래핑해서 벤더 중립적으로 SAX와 DOM 기능을 사용할 수 있게 해준다.
  • JAXP는 XML 분석 기능을 제공하지 않는다. 즉, SAX, DOM 혹은 그 이외의 XML 파싱 API 없이 JAXP만 가지고는 XML을 분석할 수 없다.
  • SAX, DOM 그리고 JDOM은 XML을 분석하는데 사용된다. 반면 JAXP는 이러한 API와 분석된 문서의 결과를 얻는 방법을 제공한다. JAXP 자체는 문서를 분석하는 새로운 방법을 제공하는 것은 아니다.
  • 결론 : JAXP는 새로운 작업을 수행하기 위한 API가 아니라 기존에 존재하는 API를 추상화시켜 특정 벤더에 종속적인 코드를 전혀 쓰지않고 하나의 단일된 형태로 사용할 수 있게 만든 중간계층이다.

JAXP 1.0 with SAX

  • SAX 1.0만 지원한다.
  • SAX 처리 파서와 함께 JAXP를 사용하려면 org.xml.sax.HandlerBase 클래스를 확장하고 애플리케이션에서 처리하려는 콜백들을 구현하면 된다. HandlerBase는 SAX 2.0의 DefaultHandler와 같은 역할을 한다.
  • JAXP는 자바 시스템 Property를 통해서 벤더 클래스의 파서를 지정할 수 있다.

SAX 사용순서

  • SAXParserFactory 클래스의 객체를 생성한다.
  • SAXParserFactory는 SAX 파서의 인스턴스를 생성하고, 파서의 옵션을 설정하는 역할을 한다.
  • SAXParserFactory에서 설정한 옵션들은 그것을 통해 얻은 모든 파서의 인스턴스에 적용된다.
    • SAXParserFactory.setNamespaceAware(boolean) : 네임스페이스 인식 여부
    • SAXParserFactory.setValidating(boolean) : 유효성 검사 여부
  • 일단 SAXParserFactory를 설정하고 나면, SAXParserFactory.newSAXParser() 메소드를 사용하여 파서에 해당하는 SAXParser 클래스(JAXP에 포함된 클래스임)의 인스턴스를 구할 수 있다.
  • SAXParser.parse()로 XML 파싱을 수행한다.
    // JAXP import
    import javax.xml.parsers.*;
    
    // SAX import
    import org.xml.sax.*;
    
    // SAXParserFactory를 얻는다.
    SAXParserFactory factory = SAXParserFactory.newInstance();
    
    // 유효성 검사를 수행하고, 네임스페이스를 인식하지 않도록 설정
    factory.setValidating(true);
    factory.setNamespaceAware(false);
    
    // SAXParser를 얻어 파싱을 한다.
    SAXParser parser = factory.newSAXParser();
    parser.parse(new File(xmlFileName), new MyHandlerBase());
    // MyHandlerBase는 org.xml.sax.HandlerBase 를 상속한 클래스이다.
    

발생 가능한 예외

  • FactoryConfigurationError : 일반적으로 파서가 사용하는 JAXP 구현 클래스나 시스템 Property를 불러올 수 없을 경우에 발생한다.
  • ParserConfigurationException : 파서에서 사용할 수 없는 특징을 설정할 때 발생한다.

SAXParser 클래스

  • SAXParser.isValidating() : 유효성 검사 수행 여부
  • SAXParser.isNamespaceAware() : 네임스페이스 인식 여부
  • SAXParser 클래스는 위 두 특징을 변경할 수 있는 메소드는 제공하지 않는다. SAXParserFactory에서 변경해야 한다.
  • SAXParser.getParser() : 내부적으로 실제 사용하는 파서의 객체(org.xml.sax.Parser의 인스턴스)

JAXP 1.0 with DOM

  • SAX와 거의 동일하다.
  • 파싱 후 Document 객체를 리턴한다.

DOM 사용 순서

  • DocumentBuilderFactory 클래스의 인스턴스를 얻는다.
  • factory 객체에서 설정할 사항들을 설정하고,
  • DocumentBuilder를 DocumentBuilderFactory로 부터 얻는다.
  • DocumentBuilder로 파싱을 수행해서 Document 객체를 얻는다.
    // DocumentBuilderFactory를 얻는다.
    DocumentBuilderFactory factory =
      DocumentBuilderFactory.newInstance();
    
    // 여러가지 설정...
    
    // DocumentBuilder 얻기
    DocumentBuilder builder = factory.newDocumentBuilder();
    
    // XML 파싱 수행
    Document doc = builder.parse(new File(xmlFileName));
    

발생 가능한 예외

SAX와 동일하다.

DocumentBuilder 클래스

  • SAX 이벤트를 처리하지 않으므로 HandlerBase 인스턴스가 필요없다.
  • DocumentBuilder.parse()는 곧바로 Document 객체를 리턴한다.
  • SAX의 ErrorHandler를 위한 DocumentBuilder.setErrorHandler()
  • SAX의 EntityResolver를 위한 DocumentBuilder.setEntityResolver()

네임스페이스?

JAXP 1.0은 네임스페이스를 처리하지 않는다. "지원"만 할 뿐이다.

JAXP 1.1은 네임스페이스를 처리할 수 있다.

파서의 변경

  • JAXP가 사용하는 파서를 변경한다는 것은 실제로 파서를 생성하는 Factory를 변경한다는 의미이다.
  • SAXParserFacotry 변경 : javax.xml.parsers.SAXParserFactory 시스템 프라퍼티로 설정
  • DocumentBuilderFactory 변경 : javax.xml.parsers.DocumentBuilderFactory 시스템 프라퍼티로 설정

JAXP 1.1

  • XSLT 프로세서는 javax.xml.transform.TransformerFactory 시스템 프라퍼티로 설정할 수 있다.

1.1에서 바뀐점

  • SAX 2.0과 DOM Level 2를 지원한다.
  • 네임스페이스를 처리한다.
  • SAX 2.0으로 넘어가면서 Parser 인터페이스는 디프리케이티드 되었다. 대신 org.xml.sax.XMLReader를 사용한다.
  • SAXParser.getXMLReader()가 추가되었다.
  • SAXParser에 SAX 2의 DefaultHandler를 인자로 받는 parse() 메소드를 추가했다.
  • SAXParserFactory.setFeature(), SAXParserFactory.getFeature()가 추가되었다.
  • SAXParser.setProperty(), SAXParser.getProperty()가 추가되었다.

TrAX API : XSL을 위한 API

  • XML 문서 변환을 벤더에 중립적으로 처리할 수 있다.
  • 다음과 같은 순서로 XSL 변환을 처리한다.
    1. TransformerFactory를 얻는다.
    2. Transformer를 얻는다.
    3. 변환을 수행한다.

Factory

  • javax.xml.transform.TransformerFactory 팩토리 객체를 생성한다.
  • 팩토리 객체에 다양한 옵션을 설정한다. 이 옵션들은 이 팩토리에서 생성되는 모든 Tansformer 인스턴스에 영향을 주게 된다.
    • 속성 설정(각 XSL 프로세서에 종속적임). TransformerFactory.setAttribute(), TransformerFactory.getAttribute()
    • ErrorListener 설정 : 분석도중에 발생하는 문제를 프로그램에서 처리시킨다. javax.xml.transform.ErrorListener 인터페이스 구현. TransformerFactory.setErrorListener()로 설정.
    • URIResolver 설정 : xsl:import 혹은 xsl:include 등에서 가져올 XML 데이터를 Source 객체로 제공해준다. 특정 URI를 만났을 때 Transformer가 여러 곳에 있는 특정 문서를 검색할 수 있게 해준다. javax.xml.transform.URIResolver 인터페이스 구현. TransformerFactory.setURIResolver()로 설정.
  • TansformerFactory.newTransformer()는 변환에 사용되는 스타일시트를 입력으로 받아들인다.

    // TransformerFactory를 얻는다.
    TransformerFactory factory = TransformerFactory.newInstance();
    
    // TransformerFactory를 구성한다.
    factory.setErrorResolver(myErrorResolver);
    factory.setURIResolver(myURIResolver);
    
    // 명시된 옵션들을 가지는 작업에 사용할 Transformer를 얻는다.
    Transformer transformer =
       factory.newTransformer(new StreamSource("foundation.xsl"));
    

XML 변환

  • 스타일시트의 위치는 반드시 그것의 위치를 나타내는 javax.xml.transform.Source의 인스턴스를 사용해 명시한다.
  • Source 인터페이스 : 스타이시트, XML 혹은 다른 정보들의 집할일 수 있는 입력의 위치
    • StreamSource : InputStream, Reader, 시스템 아이디로 입력 받음
    • DOMSource : DOM 트리에서 데이터 읽기. org.w3c.dom.Node를 인자로 받음. 이미 DOM파싱이 된 문서를 사용할 때는 DOMSource를 써야 성능이 더 좋다.
    • SAXSource : SAX 생성기로 부터 데이타 읽기. InputSource혹은 XMLReader를 입력으로 받는다. SAX 컨텐트 핸들러가 이미 사용중이고, 콜백이 설정되고 변환에 앞서 특정 작업을 처리해야 할 경우라면 SAXSource를 사용하는 것이 좋다.
  • 변환 결과는 javax.xml.transform.Result의 인스턴스로 받는다.
  • Result 인터페이스 : 변환된 문서를 출력할 목표 지정
    • StreamResult
    • DOMResult
    • SAXResult : SAX의 ContentHandler를 인스턴스로 넘겨 받는다.
      // 명시된 옵션들을 가지는 작업에 사용할 Transformer를 얻는다.
      Transformer transformer =
          factory.newTransformer(new StreamSource("foundation.xsl"));
      
      // 변환을 수행하고 결과 출력
      transformer.transform(new StreamSource("asimov.xml"),
                            new StreamResult("results.xml"));
      

SourceLocator

  • SourceLocator 인터페이스는 동작이 발생한 위치에 대한 정보를 제공한다.
  • DOMLocator 인터페이스는 처리중인 DOM 노드를 반환하는 getOriginatingNode()라는 메소드가 추가되어 있다.

OutputKeys

  • javax.xml.transform.OutputKeys 클래스는 TrAX의 변환을 위한 출력 Property를 위해 몇몇 상수를 정의하고 있다.

Templates

  • 여러번 재활용되고 다중 쓰레드에서 사용할 Transformer를 생성한다.
  • Templates 인터페이스는 출력 Property의 집합을 여러 개의 변환작업에 똑같이 적용하고 싶거나, 변환 지시어들의 집합을 연속적으로 사용하고 싶을 때 사용한다.
    TransformerFactory factory = TransformerFactory.newInstance();
    
    // Templates 객체를 얻는다.
    Template template =
        factory.newTemplates(new StreamSource("html.xsl"));
    
    // Transformer의 인스턴스를 얻는다.
    Transformer transformer = template.newTransformer();
    
    // 변환
    transformer.transform(new DOMSource(orderForm), new StreamResult(res.getOutputStream()));
    
  • 하나의 스타일시트를 두 번이상 사용하면 Templates 객체를 사용하는 것이 좋다.
  • XSL 스타일시트를 자바 객체로 변환하는 과정을 반복하지 않으므로 더 성능이 좋다.
  • 다중 쓰레드 환경에서는 Templates 꼭 사용해야 한다.

JAXP 설정

$JRE_HOME/lib/ext 디렉토리에 jaxp.properties 파일을 만들고 원하는 팩토리를 설정해 둘 수 있다.

+ Recent posts