개발일기장

JDOM (java xml parser) (1) read 본문

JAVA

JDOM (java xml parser) (1) read

게슬 2023. 1. 29. 22:57
728x90

회사에서 쓰는 프레임워크가 통신을 할때 TIB rv에 XML형식으로 주고받는 .. 그런 방식이다.

Springboot에서는 httpRequest객체를 받는데 사내 프레임워크엥서는 Document(JDOM에 있음) 이거를 받아옴

그래서 할것도 없고 해두면 괜찮겠다 싶어서 JDOM에서 뭘 할 수 있나 좀 보자


일단 이분이 작성한 블로그랑 java doc을 보면서

https://www.joinc.co.kr/w/Site/XML/JDOM_xml_Processing

 

JDOM을 이용한 xml 데이터 처리

JDOM을 이용한 xml 데이터 처리음.. C(그게 어쩌다보니, java를 이용해서 처리해야 하는 필요가 생겼다. 두가지 언어 모두 별로 익숙하지 않다는게 맘에 걸린다. 역시나. 일단 용어부터가 문제다. 무

www.joinc.co.kr

 

1. library 추가

http://www.jdom.org

여기서 다운받고 빌드된 파일을 외부 라이브러리로 추가해주자

File -> Project Structure -> Modules -> + -> JARS 여기서 build폴더 내부의 jar을 추가해주면 끝임 

사실 내가 이거 intelliJ에서 어캐하는지 몰라서 적어둠......

근대 일반적으로는 Maven이나 Gradle에서 설정만 하면 다 끌어올 수 있어서 일반적으로 이렇게 할 필요는 없을거같다.


2. 기본적인 사용법

일단 xml파일을 하나 만드록 저 (근대 왜 티스토리에서 코드 박스에 html은 있는데 xml은 없음?)

<?xml version="1.0" encoding="UTF-8"?>
<body 요일="월" val="출근하기싫다">
    <schme schema="type" type="lang" />
    <para lang="Java" />
    <para lang="NodeJS" />
    <para lang="C++" />
    <ext>
        <value>132423</value>
        <type>real</type>
    </ext>
</body>

 

 일단 파일을 읽어오는 코드 작성 ㄱㄱ

2-1. TAG

package com;

import org.jdom.*;
import org.jdom.input.*;

public class Main {
    public static void main(String[] args) {
        try{
        
            SAXBuilder sb = new SAXBuilder();
            Document doc = sb.build("hello.xml");
            Element root = doc.getRootElement();
            System.out.println("Root Node : " + root.getName());

        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

이러고 실행을 시키면 root tag이름을 확인 할 수 있다.

getrRootElement() 사용해서 xml파일을 읽으면 가장 밖의 tag를 읽어낸다.

여기서 getName()는 그 tag의 이름을 보는 기능임

result

2-2. 속성

그리고 root tag(body)에 딸려있는 다른 속성 값들을 가지고 오자

List attrList = root.getAttributes();  // -> 지금 해당하는 tag의 모든 속성을 가지고 옴
for(Object o : attrList){
    Attribute attr = (Attribute) o;		// Attribute로 type변환
    System.out.println(attr.getName() + " : " + attr.getValue()); // getName, getValue
    System.out.println(root.getAttribute(attr.getName()).getValue());
}

getAttributes를 사용하면 모든 속성을 가지고 오고 getAttribute( 속성이름 )을 사용하면 원하는 속성을 가지고 올 수 있다.

result

근대 tag이름을 가지고 올 때에도 getName()이고 속성의 이름을 가지고 올 때에도 getName()이라서 좀 해깔리긴 하는데

일반적으로 속성의 이름은 이미 정의된 상태에서 사용하니깐 getAttributes를 사용 할 일도 잘 없을것 같아서 속성값을 가지고 오기 위한 getValue()만 기억해 두면 될 것 같다.


3. Child

이제 밑으로 더 내려가야한다

3-1. getChild()

getChild()랑 getChildren이 있는데 tag이름이 같은 경우가 있고 그렇지 않은 경우가 있으니깐 두개 다 확인해보자.

위에 xml파일에서는 body태그 밑에 schme 태그는 하나고 para는 여러개인 것을 볼 수 있다.

 

일단 위에서 속성 다 돌아가는 코드는 method로 추출하자.

    private static void printAttribute(Element element) {
        for(Object o : element.getAttributes()){
            Attribute attr = (Attribute) o;
            System.out.println(attr.getName() + " : " + attr.getValue());
        }
        System.out.println();
    }

그리고 getChild(tag이름)을 사용하자

            Element schme = root.getChild("schme");
            printAttribute(schme);
            Element para1 = root.getChild("para");
            printAttribute(para1);

result

schme tag와 para tag를 각각 확인해보면 이런 결과를 볼 수 있다 para tag의 경우 가장 위에 있는것으로 확인이 된다..

            Element schme = root.getChild("schme");
            printAttribute(schme);
            Element para1 = root.getChild("para");
            printAttribute(para1);
            Element para2 = root.getChild("para");
            printAttribute(para2);

result

그냥 파일을 읽어서 쭉 내려가는게 아닐까 싶어서 한번 더 읽어봐도 같은 결과를 확인 할 수 있다.

 

3-2.getChildren()

getChildren은 3가지 오버로딩이 있는데 namespace는 지금 몰라서 생략 ㅎㅎ..

일단 아무 파라미터를 넣어주지 않으면 그 밑에 있는 모든 tag를 읽어온다

근대 tag이름 print하는거 귀찮으니 이것도 method로 빼주자

    private static void printElement(Element e) {
        System.out.println("Tag : " + e.getName());
        printAttribute(e);
    }
            List tagList = root.getChildren();
            for (Object child : tagList) {
                Element e = (Element) child;
                printElement(e);
            }

result

getChildren()을 하면 해당 element밑의 모든 tag를 담은 Object List를 반환한다.

이것을 foreach방식으로 읽으면 이렇게 값을 받아올 수 있다.

 

그리고 전부가 아니라 원하는 tag들의 list를 읽어올 수 있게 하려면 getChildren(tag) 를 사용하면 된다.

            List tagList = root.getChildren("para");
            for (Object child : tagList) {
                Element e = (Element) child;
                printElement(e);
            }

result

그러면 이런 결과를 볼 수 있다.

일단 파일내용 읽는거는 이정도 함수만 알면 되나..?(namespace는 언제함)

 


# 전체 탐색

    private static void searchTag(Element e){
        printElement(e);
        for(Object tagList :e.getChildren()){
            searchTag((Element) tagList);
        }
    }

result

제귀적인 방식으로 xml파일 전부를 읽어오는 method를 작성해보면 이렇게 생각해 볼 수 있을 것 같다.

근대 생각해보니깐 그냥 속성이 아닌 값 받아오는거를 까먹음

요놈

    private static void printElement(Element e) {
        System.out.println("Tag is " + e.getName() + " - " + e.getValue());
        printAttribute(e);
    }

result

그래서 printElement를 조금 수정해봤는데 이런 결과가 나온다.. 그냥 tag사이에 값을 넣으면 그 밑에 있는거 까지 다 가지고 오는 그런 느낌임.. 주의해서 사용해야 할 것 같다.

-> 자기꺼만 특정해서 값을 가지고 오는 method가 없는거 같음.. version이 달라서 그런가 ㅜㅜㅜㅜ


# 전체 코드

package com;

import org.jdom.*;
import org.jdom.input.*;

import java.util.List;

public class Main {
    public static void main(String[] args) {
        try {
            SAXBuilder saxBuilder = new SAXBuilder();
            Document doc = saxBuilder.build("hello.xml");
            Element root = doc.getRootElement();
            //System.out.println("Root Node : " + root.getName());

            //printAttribute(root);

//            Element schme = root.getChild("schme");
//            printAttribute(schme);
//            Element para1 = root.getChild("para");
//            printAttribute(para1);
//            Element para2 = root.getChild("para");
//            printAttribute(para2);

//            List tagList = root.getChildren();
//            for (Object child : tagList) {
//                Element e = (Element) child;
//                printElement(e);
//            }

//            List tagList = root.getChildren("para");
//            for (Object child : tagList) {
//                Element e = (Element) child;
//                printElement(e);
//            }
            searchTag(root);


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void searchTag(Element e){
        printElement(e);
        for(Object tagList :e.getChildren()){
            searchTag((Element) tagList);
        }
    }

    private static void printElement(Element e) {
        System.out.println("Tag is " + e.getName() + " - " + e.getValue());
        printAttribute(e);
    }

    private static void printAttribute(Element element) {
        for (Object o : element.getAttributes()) {
            Attribute attr = (Attribute) o;
            System.out.println(attr.getName() + " : " + attr.getValue());
        }
        System.out.println();
    }
}

평소에  javascript랑 json방식을 주로 사용하다 보니깐 spring boot에서의 dto정도까지는 불편해도 써먹을 만 했는데

xml로 넘어가니깐 하나하나 다 확인을 해주는 방식이니 좀 복잡한것보다는 귀찮은것 같다.

아직 많은 시스템에서 xml을 사용한 통신이라던가 config파일을 사용하고 있으니 이런거 공부해두는게 좋을 것 같다.

 

안그래도 Maven도 해야하는데 이것도 xml방식이었던거같음


 

이거에 reflection 사용해서 dto로 바꾸는 방법이 뭐 없을까 생각해보고 있는데

사실 reflection도 잘 몰라서 이번주는 퇴근하고나서 jdom이랑 reflection 공부할 계획

 

728x90
Comments