XML파일의 활용

밥벌이/Java 2015. 9. 18. 22:21

1. xml 파일 생성하기

- 일반적으로 xml 파일은 정적인 설정정보를 저장하기 위한 용도로 사용되며 

어플리케이션에서 해당 정보를 읽어서 사용한다. 

이러한 이점으로 인해 자주 변경되야 하는 설정정보의 경우 xml파일로 작성하여 

수정이 있을 때 별도의 소스 컴파일 과정없이 확장이 가능하게 된다.

다수의 설정정보를 저장하는 만큼 파일 내에서 필요한 데이터를 

효율적으로 파싱하기 위해 기본적인 구조는 트리구조를 가지고 있다.

 

기본적인 작성형식은 아래와 같다.

<?xml version=”1.0” encoding=”UTF-8”?>

<movieList>

<movie>

<name>신의한수</name>

<creator>조범구</creator>

<genre>액션</genre>

</movie>

<movie name = “트랜스포머”>

<option name = “creator">마이클베이</option>

<option name = “genre”>SF</option>

</movie>

</movieList>

  

- <?xml version=”1.0” encoding=”UTF-8”?> 의 경우 해당 파일이 xml 파일임을 

명시하는 것으로 반드시 최상단에 들어가야 한다. encoding 값 설정의 경우 선택적이긴 

하지만 한글을 사용할 것이라면 위와 같이 UTF-8로 지정해 주는 것이 좋고, 대부분 그렇게 사용한다.

* 주의할 점은 XML 파일에서는 대소문자를 철저히 구분하므로 

위 예시처럼 대소문자를 가리지 않거나 “”를 생략한다면 에러가 발생한다.

 

- 아랫 줄 부터는 실제 사용할 정보를 기술한다. 

<movieList></movieList>와 같이 반드시 종료태그를 기술해야 한다.

 

- <movieList> 와 같이 가장 바깥쪽에 있는 태그를 Root Element라고 하며 

반드시 1개만 존재할 수 있다. 1개 이상 존재한다면 읽어올 때 에러가 발생한다.

 

-  아래로 보이는 <movie> 태그로 2개의 영화에 대한 정보를 기술하였다.

정보 기술의 경우 첫번째 영화(신의한수)처럼 단순노드만으로도 구성이 가능하며 

두번째 영화(트랜스포머)처럼 속성을 포함한 노드로도 구성이 가능하다.

 

- 처음에 말했듯이 XML은 기본적으로 트리구조를 가지고 있기 때문에 

각 정보에 접근하는 방식은 node와 element로서 접근하게 된다. 

node는 단순히 해당 경로의 접점을 의미하며 element의 경우 경로와 

요소를 포함한 객체를 의미한다. 

이러한 이유로 위 xml에서 '신의한수' 라는 정보를 얻고자 한다면 

<move> -> <name> 와 같이 node만으로 접근하고 해당 텍스트를 얻어오면 되지만 

'트랜스포머'라는 정보를 얻고자 한다면 <movie> -> <option> node로 접근한 뒤 

element로 형변환한뒤에 name 속성에 해당하는 을 얻어와야 한다.

 

 



2. xml 파일 읽기
- 기본적으로 XML 파일을 읽기 위해서는 아래의 과정을 거친다.

 모든 방식의 접근방식을 기술한 것이 아니라 본인이 활용하거나 습득한 정보만

나열되어 있기 때문에 하나의 예시로써 활용하고 추가로 필요한 부분은 검색 또는 API를 참고해야 할 것 같다.


읽어올 XML 파일의 내용은 아래와 같다.

<?xml version=”1.0 encoding=”UTF-8”?>

<confList>

<confResource name = “ExcelCompare”>

<option name = “basePath”>d:/업무/요청자료/</option>

<option name = “target_fileName”>전체 사용자목록.xls</option>

<option name = “standard_fileName”>A팀 현재 사용자목록.xls</option>

<option name = “result_fileName”>A팀 정상 사용자목록.xls</option>

</confResource>

<confResource name = “...”>

...

</confResource>

</confList>


해당 설정파일의 경우 ‘A팀 현재 사용자목록’ 중 ‘전체 사용자목록’에 포함되지 않는 사용자들을 비교하여

삭제한 뒤 결과 엑셀파일을 새로 생성하는 자바어플리케이션 개발시 사용되었다.
추후 <confResource> 태그를 하단에 추가하여 name 속성에 각각의 프로세스명을 기입하여

다른 자바어플리케이션 개발시에도 함께 활용할 계획이었다.



2.1. Document 객체 생성


DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();


// classpath 상에 존재하는 설정파일을 읽어올 때
InputStream is = getClass().getResourceAsStream(“/conf/DestinyConf.xml”);
Document d = db.parse(is);


/*
classpath 상에 존재하지 않는 설정파일을 읽어올 때
File confFile = new File(“d:/conf/DestinyConf.xml”);
Document d = db.parse(confFile);
보이는 것 처럼 DocumentBuild의 parse() 메소드는 오버로딩 되어있어 InputStream, File 중 아무거나 받을 수 있다.
*/


d.getDocumentElement().normalize();



2.2. Root Element 값 얻기


d.getDocumentElement().getNodeName();



2.3. 설정파일 리스트 얻어오기


NodeList confList = d. getElementsByTagName (“confResource”);

- confResource 라는 태그명을 가지는 모든 node 리스트를 얻어온다.



2.4. 설정파일 리스트에서 현재 프로세스에서 사용할 설정파일에 맞는 자원 찾기

for(int i = 0; i < confList.getLength(); i++){
/* confResource라는 태그명을 가진 node를 순차적으로 돌면서 해당 프로세스의 설정정보로 지정된 node를 찾는다. */


 Element confResource = (Element)confList.item(i);
 /* 단순히 node로 접근하는 것이 아닌 name속성을 체크해야 하므로 Element 로 변환한다. */


 if(confResource.getAttribute(“name”).equals(“ExcelCompare”)){
 /* name 속성이 해당 프로세스인 것을 찾는다. */


  NodeList confResourceList = confResource.getElementsByTagName(“option”);
  /* 해당 노드 안에는 프로세스에서 사용할 option 값들이 여러 노드로 분배되어 있기 때문에

      option 태그를 가지는 node들로 리스트를 생성한다. */


  for(int j = 0; j < confResourceList.getLength(); j++){
   /* 해당 node 리스트를 돌면서 필요한 설정값을 읽어서 설정한다.*/


   Element option = (Element)confResourceList.item( j);
   String optionName = option.getAttribute( "name");


   if(optionName.equals( "basePath")){
    basePath = option.getTextContent(); //해당 node의 텍스트 자원을 얻어온다.
   }else if(optionName.equals("target_fileName")){
    target_fileName = option.getTextContent();
   }else if(optionName.equals( "standard_fileName")){
    standard_fileName = option.getTextContent();
   }else if(optionName.equals("result_fileName")){
    result_fileName = option.getTextContent();
   }
  }
 }
}

'밥벌이 > Java' 카테고리의 다른 글

VO, DTO 구분해서 사용해야 할까?  (0) 2020.07.16
BufferedStream 팁  (0) 2015.09.18
Properties 파일 읽기  (0) 2015.09.18
Posted by mypiece
,