반응형

소스참조: http://www.ibm.com/developerworks/library/x-tipent.html

원인)
xml validation을 하다보면 (builder.parse~~부분)
xml파일이 있는 경로에 dtd이 없거나, 현재 시스템이 사용중인 디렉토리에서 계속 dtd를 읽어들어
dtd파일을 찾을 수 없어 validation을 처리할 수 없는 경우를 종종 경험했다.

예) xml 문서에
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Message PUBLIC "-//LEE//JIN" "TEST.dtd">
...............
와 같이 되어있다면 /../../../TEST.dtd 지정된 경로에 파일을 찾을 수 없습니다.


해결방법)
EntityResolver을 사용하는 것이다.
EntityResolver를 사용하면 외부의 dtd를 두고 xml을 파싱하여 validation을 체크할 수 있다.
EntityResolver는

The Parser will call this method before opening any external entity except the top-level document entity (including the external DTD subset, external entities referenced within the DTD, and external entities referenced within the document element): the application may request that the parser resolve the entity itself, that it use an alternative URI, or that it use an entirely different input source.



소스)
class DTDResolver implements EntityResolver {
    public InputSource resolveEntity(String publicID, String systemID)
        throws SAXException {
     System.out.println(systemID.toString());
        if (systemID.equals("TEST.dtd")) {
            // Return local copy of the copyright.xml file
            return new InputSource("/lee/jin/test/TEST.dtd");
        }
        // If no match, returning null makes process continue normally
        return null;
    }
}


여기서 pulbicId와 Systemid를 받는데 xml의 doctype을 보면
<!DOCTYPE Message PUBLIC "-//LEE//JIN" "TEST.dtd">
"-//LEE//JIN" 가 publicID, "TEST.dtd"가 SystemID 이다.

그렇기에 xml문서에서 "TEST.dtd"를 만나게 되면 "/lee/jin/test/TEST.dtd"를 리턴하라는 것이다.

즉 어디에 있는 xml을 불러들이건 특정 한 경로에 dtd파일이 있으면 그것을 참조하여 xml을 파싱하기때문에 여러곳에 dtd를 넣고 작업하지 않아도 된다.

(만약 위와같이 했는데도 TEST.dtd를 찾지 못한다면 SystemID.endsWith를 사용하여 처리하면 해결 할 수 있다.)



API참고: http://download.oracle.com/javase/1.4.2/docs/api/org/xml/sax/EntityResolver.html
반응형
반응형

DTD를 기준으로 validation을 할때 사용하는 소스이다.

참조: http://www.roseindia.net/xml/dom/DOMValidateDTD.shtml

import java.io.FileInputStream;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

public class DOMValidateDTD {
 public static void main(String args[]) {
  String msg=null;
  try {
   DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
   factory.setValidating(true);
   DocumentBuilder builder = factory.newDocumentBuilder();
   

   builder.setErrorHandler(new org.xml.sax.ErrorHandler() {
    // Ignore the fatal errors
    public void fatalError(SAXParseException exception)
      throws SAXException {
    }

    // Validation errors
    public void error(SAXParseException e) throws SAXParseException {
     System.out.println(e.getMessage());
    }

    // Show warnings
    public void warning(SAXParseException err)
      throws SAXParseException {
     System.out.println(err.getMessage());
    }
   });
   
   builder.setEntityResolver(new DTDResolver());
   
   Document xmlDocument = builder.parse(new FileInputStream(
     "Test.xml"));
   
   DOMSource source = new DOMSource(xmlDocument);
   StreamResult result = new StreamResult(System.out);
   StreamResult result = new StreamResult(System.out);
   TransformerFactory tf = TransformerFactory.newInstance();
   Transformer transformer = tf.newTransformer();
   transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,  "");
   transformer.transform(source, result);
  } catch (Exception e) {
   System.out.println(e.getMessage());
  }
 }
}

1. builder.setEntityResolver(new DTDResolver()); 
- 외부 dtd가 있는 경우 그것을 참조하게 설정해 주는 DTDResolver라는 EntityResolver를 상속받는 클래스를 구현한 것이다.

2. builder.setErrorHandler(new org.xml.sax.ErrorHandler()
- 파싱중에 발생하는 에러를 처리하는 부분이다.
ㄱ. warning - 오류취급 하지 않지만 사용자에게 전달해야 할때
ㄴ. error - xml 1.0권고안 오류, 파서 더이상 실행하지 않음.
ㄷ. fatal error - 오류로 인해 파서의 계속적 수행불가 (태그 열리고 닫히는 것)

3.    Document xmlDocument = builder.parse(new FileInputStream("TEST.xml"));
xml문서를 파싱하는 부분이다.

4.    DOMSource source = new DOMSource(xmlDocument);
   StreamResult result = new StreamResult(System.out);
   TransformerFactory tf = TransformerFactory.newInstance();
   Transformer transformer = tf.newTransformer();
   transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,
     "");
파싱한 문서를 다시 Transformer객체를 이용해서 xml문서를 생성해 주는 부분이다.
setOutputProperty를 사용하여 만들고자 하는 xml을 원하는 값으로 넣어준다.
위와같이    transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, ""); 로 한다면
만들어진 xml확인시 DOCTYPE이 공백으로 나올 것이다.

반응형
반응형
DTD - Attributes

사용법: <!ATTLIST element-name attribute-name attribute-type default-value>
값 : CDATA - Character data, ID - Unique id, IDREF-Id of another Element 등등
디폴트값 : #DEFAULT value - defualt value,
               #REQUIRED -  the attribute value must be included in the element.
               #IMPLIED - the attribute does not have to be included.
               #FIXED value - the value is fixed.
예)
<!ELEMENT ACRCRS_Individual (Discipline_List*, Optional_Function*)>
<!ATTLIST ACRCRS_Individual
 Registration_Number CDATA #REQUIRED
 Gender_ID %GENDER; #IMPLIED
>

참조: http://www.xmlfiles.com/dtd/dtd_attributes.asp

반응형
반응형

Caused by: java.lang.NoClassDefFoundError: org/jdom/Content
 at com.gms.ent.download.ENTDownloadManager.<init>(ENTDownloadManager.java:55)
 at com.gms.ent.download.ENTDownloadAction.getENTDownloadManager(ENTDownloadAction.java:374)
 at com.gms.ent.download.ENTDownloadAction.fileList(ENTDownloadAction.java:132)
 ... 54 more
Caused by: java.lang.ClassNotFoundException: org.jdom.Content
 at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1340)
 at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1189)
 ... 57 more


해결방법
external jar파일인 경우 WEB-INF/lib 디렉토리 밑에 파일을 넣고 해야한다.

출처: http://www.coderanch.com/t/77967/Websphere/WSAD-JDOM
반응형

+ Recent posts