2017.04.19 07:56

[Java] XStream을 사용한 XML 파싱




XStream 라이브러리를 사용하여 XML 파싱하는 예제소스 입니다.



build.gradle 에 라이브러리 추가 (Gradle 사용 시)

// https://mvnrepository.com/artifact/com.thoughtworks.xstream/xstream

compile group: 'com.thoughtworks.xstream', name: 'xstream', version: '1.4.9' 


Gradle 사용하지 않고 진행 시 라이브러리는 직접 다운받아서 추가해 줍니다.



main 소스

package xmlparse;


import java.net.URL;

import java.net.URLConnection;


import com.thoughtworks.xstream.XStream;

import com.thoughtworks.xstream.io.xml.DomDriver;


import xmlparse.vo.Book;

import xmlparse.vo.Catalog;


public class xmlparse {


public static void main(String[] args) throws Exception {


// XStream 인스턴스 생성

        XStream xstream = new XStream(new DomDriver());

        

        // alias 설정 XML tag, 담당할 class 지정

        // 각 클래스는 해당 태그가 가진 항목을 구성하고 있다

        xstream.alias("catalog", Catalog.class);

        xstream.alias("book", Book.class);

        xstream.addImplicitCollection(Catalog.class, "books");

        

        // 태그의 어노테이션 처리 

        // <book id="xxx"> 에서 xxx 를 읽어오기 위해 필요하다

        // [REF] http://stackoverflow.com/questions/18106619/xstreamasattribute-not-adding-as-attribute-xstream

        //xstream.autodetectAnnotations(true);  // auto 속성을 지정하게 되면 모두 처리하는 듯 하다. (귀찮으면 걍 이거 쓰자 ;;)

        xstream.processAnnotations(Book.class); // 각 속성별로 읽어오도록 지정 한다.

        

        // XML 로드

        URL url = new URL("http://haebi.net/book.xml");

        URLConnection conn = url.openConnection();

        

        // 최상위 태그로부터 XML 파싱

        Catalog var = (Catalog)xstream.fromXML(conn.getInputStream());

        

        // 반복문 돌면서 처리한다

        for(int i=0; i<var.books.size(); i++)

        {

        Book book = var.books.get(i);

        System.out.println(book.id);

        System.out.println(book.author);

        }

        

}


book.java

package xmlparse.vo;


import com.thoughtworks.xstream.annotations.XStreamAlias;

import com.thoughtworks.xstream.annotations.XStreamAsAttribute;


@XStreamAlias("book")

public class Book {

@XStreamAsAttribute

    public String id;

public String author;

public String title;

public String genre;

public String price;

public String publish_date;

public String description;

// 갯수가 멀티개인 속성을 가지면...

//@XStreamImplicit(itemFieldName="reply")

//private ArrayList<string> reply

}


catalog.java

package xmlparse.vo;


import java.util.LinkedList;

import java.util.List;


import com.thoughtworks.xstream.annotations.XStreamAlias;

import com.thoughtworks.xstream.annotations.XStreamAsAttribute;


@XStreamAlias("catalog")

public class Catalog {

public List<Book> books = new LinkedList<Book>();

}



Depth 가 낮은 XML 처리에는 유용하겠는데, 깊어지면 답이 없어 보인다. ;;;

10 depth 까지 내려가면 클래스 언제 다 맹글어 -_-;;




Posted by 해비
2017.04.18 01:54

XPath를 활용한 XML 파싱



syntaxhighliter 에서 코드가 뭉개져서 그냥 붙여넣기 했더니 보기가 영 그렇다.


gist 에 올린 소스가 더 이쁘게 보여지므로 참고

[gist 링크] https://gist.github.com/haebi/29070dda0556fc6fba5909b45a067faa



소스코드

package xmlparse2;


import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.xpath.XPath;

import javax.xml.xpath.XPathConstants;

import javax.xml.xpath.XPathFactory;


import org.w3c.dom.Document;

import org.w3c.dom.NodeList;


public class XmlParse2 {


public static void main(String[] args) throws Exception {

// 샘플 XML 파일(books.xml)

// [REF] https://msdn.microsoft.com/ko-kr/library/ms762271(v=vs.85).aspx

Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse("http://haebi.net/book.xml");

// XPath 인스턴스 생성

XPath xpath = XPathFactory.newInstance().newXPath();

// 대상 노드 지정

String expression = "/catalog/book";

// 지정 노드로 부터 노드목록 획득

NodeList nl = (NodeList) xpath.evaluate(expression, doc, XPathConstants.NODESET);

// 첫번째 노드의 부모 노드명을 출력

System.out.println(nl.item(0).getParentNode().getNodeName());

System.out.println("sub node start!!");

System.out.println("-----------------------------------------------------");

// 1번째  book 노드의 자식노드 목록을 획득

NodeList cnl = nl.item(0).getChildNodes(); // author, title, genre, price, publish_date, description

System.out.println(cnl.item(0).getParentNode().getNodeName());


// 확보된 노드 목록을 순서대로 출력

for(int i=0; i<cnl.getLength(); i++)

{

// 노드 이름이 #text로 출력되는 문제로 스킵 하도록 설정하였다. 

// xml파일의 들여쓰기로 인한 문제 인듯 하다.

if("#text".equals(cnl.item(i).getNodeName()))

continue;

// 현재 노드 인덱스 번호 출력

System.out.println(i);

// 노드 명 출력

System.out.println("NODE : " + cnl.item(i).getNodeName());

// 노드 값 출력

System.out.println("VALUE : " + cnl.item(i).getTextContent());

}

System.out.println("-----------------------------------------------------");

}

}



출력

Start!!

catalog

sub node start!!

-----------------------------------------------------

book

1

NODE : author

VALUE : Gambardella, Matthew

3

NODE : title

VALUE : XML Developer's Guide

5

NODE : genre

VALUE : Computer

7

NODE : price

VALUE : 44.95

9

NODE : publish_date

VALUE : 2000-10-01

11

NODE : description

VALUE : An in-depth look at creating applications 

      with XML.

----------------------------------------------------- 




Posted by 해비
2015.01.28 13:11

Oracle JDK 설치

리눅스에 기본 설치된 OpenJDK 또는 JRE ? 대신 오라클에서 제공하는 자바 가상머신 설치 방법에 대해 설명합니다.


모든 과정은 Root 권한으로 진행합니다.

매 구문마다 sudo 명령어를 붙여서 진행해도 되지만 불편하다면 su - root 로 아예 루트권한으로 바꾼 후 작업 합니다.




다운로드

오라클 사이트에 가서 최신 자바 JDK를 다운로드 합니다.

http://www.oracle.com/technetwork/java/index.html




­압축해제

# tar ­-zxf jdk-­8u31-­linux­-x64.tar.gz ­-C /opt/jdk/

- 표시된 부분의 파일명은 JDK 버젼과 OS 버젼에 따라 다릅니다. 알아서 수정할 것!




설치확인

# ls /opt/jdk/
jdk1.8.0_31

- ls 명령어 실행 시, jdk어쩌고 폴더가 리스트에 있다면 성공적으로 설치된 것 입니다.


기본JDK설정 (2개 다 실행한다)

# update­alternatives --­­install /usr/bin/java java /opt/jdk/jdk1.8.0_05/bin/java 100
# update­alternatives ­­--install /usr/bin/javac javac /opt/jdk/jdk1.8.0_05/bin/javac 100

(노란배경 부분은 설치확인 명령에서에 확인된 폴더명으로 버젼에 맞게 수정한다.)

- java, javac 명령어 입력 시 현재 설치된 것을 불러오도록 설정 합니다.


기본설정 확인

# update­alternatives ­­--display java
# update­alternatives ­­--display javac

- ­ 자바 버젼을 계속 구 버젼 참조하면 우선순위 변경(표시된 위치는 알아서 시스템에 맞게 수정)




우선순위 변경

# update­alternatives ­­--install /usr/bin/java java /usr/lib/jvm/java­6­openjdk­amd64/jre/bin/java 90

- 맨 뒤의 숫자가 클 수록 우선순위가 높다. 우리가 설정한 수치는 100 이었으므로 100 보다 작은 수로 지정을 한다.

- 기존 것 손대기 싫다면, 저위에 수치를 100 대신 기존 수치 보다 더 높은 값으로 지정해 주면 된다.






- 참고 -

https://www.digitalocean.com/community/tutorials/how­to­manually­install­oracle­java­on­a­debian­or-
ubuntu­vps






Posted by 해비
2011.04.13 10:52

1. exam01.java 소스코드 작성

묵시적 형 변환에 관련된 예제 입니다.


3 - short형 변수 S01 에 10을 대입합니다.
4 - short형 변수 S02 에 20을 대입합니다.
5 - short형 변수 S03 에 10+20의 결과를 대입합니다.
6 - short형 변수 S04 에 변수S01 과 변수 S02를 더한다음 그것의 결과를 대입합니다.*
7 - long형 변수 S05 에 변수S01 과 변수 S02를 더한다음 그것의 결과를 대입합니다.


저장 후, 컴파일 하면 에러가 발생합니다.

6번째 라인에서 오류가 발생했음을 알리는 메시지 입니다.


이유....
자바에서 연산을 하면서 변수 타입이 기본으로 자동 지정되어졌기 때문입니다.
정수 + 정수 에서 기본 데이터 타입이 int 형인데 이것을 int보다 작은 크기인 short 에 넣겠다고 해서 발생한 오류입니다.


[해결 방법]
방법1 - 연산 부분을 괄호로 묶고 앞에 명시적 형 변환을 합니다.
           short S04 = (short)(S01+S02)

방법2 - 변수 S04의 타입을 int 형으로 선언 합니다.
         int S04 = S01+S02

방법3 - 변수 S04의 타입을 String 형으로 선언 하고, 뒤에 +"" 를 추가하여 문자화 합니다
           (주의! - 방법3 의 경우, 데이터가 문자열로 인식됩니다.)
           String S04 = S01+S02+""



* 자바에서 연산시 기본으로 지정되는 데이터 타입
정수연산 - int
실수연산 - double
문자결합 - String

정수 + 정수 = int
정수 + 실수 = double
정수 or 실수 + "문자" = String


그냥 간단하게...
작은 크기에서 큰 크기로 형 변환은 자동(묵시적)으로 이루어 지지만, 그 반대 의 경우에는 반드시 명시적으로 형 변환을 해 주어야 합니다.

보다 자세한 데이터타입이나 크기는 검색을...
Posted by 해비
2011.04.05 10:44

1. Hello.java 소스코드 작성

단 5줄 짜리의 초간단 예제 입니다.
(에디트 플러스, 메모장, 이클립스 기타... 어떤 툴을 사용하셔도 상관없습니다)



2. 컴파일
javac Hello.java

Hello.java 파일이 있는 경로로 가서 위와 같이 컴파일을 합니다.
.class 파일이 결과물로 생성됩니다.



3. 실행
java Hello

위 소스코드의 3번째 라인에 있는...
Hello World!
가 출력되면 정상적으로 컴파일 및 실행이 된 겁니다.

주의 : 실행 시, 확장자는 적으면 안됩니다.
예) java Hello.class -> 실행 안됨!!




public static void main(String[] args)
또는
public static void main(String args[])
어느쪽이든 좋습니다.

public - 접근제어를 뜻합니다. (공개 - 클래스내부, 외우 어디에서든 접근 가능)
static - 공유를 의미합니다. (모든 객체에서 공통으로 사용)
void - 리턴값이 없음을 의미 합니다.
(보다 자세한 내용은 뒤에서 다루겠습니다)

String[] args 는 실행시 매개변수를 받아오기 위한 용도로 쓰여집니다.
java Hello [매개변수1] [매개변수2] [...]


public static void main(String[] args)는 형식이 딱 지정되어있으므로 암기해 두는것이 좋습니다.
자바에서 프로그램의 시작점이 되는 곳입니다.


매개변수의 구분은 스페이스(띄움) 이며, 각 매개변수는 배열로 받아오게 됩니다.

그렇게 조금 변경된 Hello.java 의 소스코드 입니다.

args[0]
args[1]
의 2개의 매개변수를 받아와서 출력하는 구분이 추가되었습니다.

컴파일 후,
실행시 뒤에 관련 매개변수값(아무거나...) 넣어주시면 되겠습니다

위와 같이 실행이 되어집니다.

그런데,
매개변수가 모자르거나 아예 없을경우는 에러가 발생합니다.

위 코드를 보면 4번째 라인에서 오류가 발생하였음을 알리고 있습니다.

즉, 매개변수 배열의 0번째가 존재하지 않는데 0번째의 값을 가져다 쓰려고 한다고 예외가 발생했음을 알립니다.

이것마저 해결하고자 한다면은...
try~ catch 구문을 이용하여 오류 발생시 catch 블럭으로 처리를 던지는 식으로 오류 처리를 할수 있습니다만, 여기서 이것까지 하지는 않습니다.
다만, 이런 방법도 있다는 것을 알려드립니다.
(자세한 내용은 뒤에서 다루도록 하겠습니다)



[체크 사항]
Java 소스파일의 파일명은 main 메소드가 포함된 클래스의 명으로 지정하여야 한다!



Posted by 해비
2010.11.24 17:23

http://java.sun.com 또는
http://www.oracle.com/technetwork/java/index.html 에서 JDK최신버젼을 내려 받습니다.

플랫폼과 버젼 확인하고 끝에 .rpm.bin 으로 된것을 다운로드 합니다.

wget http://cds.sun.com/is-bin/INTERSHOP.enfinity/WFS/CDS-CDS_Developer-Site/en_US/-/USD/VerifyItem-Start/jdk-6u22-linux-x64-rpm.bin?BundledLineItemUUID=FX6J_hCxXAEAAAEst9kF_JVT&OrderID=uRqJ_hCx8c8AAAEsrNkF_JVT&ProductID=w9aJ_hCw9PAAAAErNFJuIQy3&FileName=/jdk-6u22-linux-x64-rpm.bin

chmod 755
실행권한 설정

./jdk-6u22-linux-x64-rpm.bin

중간에 엔터 한번 누르라고 나오는데 눌러줍니다.

성공적으로 설치가 된 경우
java -version
자바의 버젼이 표시됩니다.

javac -version 도 동일....





Posted by 해비