developer life/java

[java] xpath를 이용한 xml 파싱(Parsing) example

노는개발자V 2023. 11. 17. 15:14
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<list>
<item>
<title><![CDATA[제목입니다1]]></title>
<content><![CDATA[내용입니다.]]></content>
</item>
<item>
<title><![CDATA[제목입니다2]]></title>
<content><![CDATA[내용입니다2.]]></content>
</item>
<item>
<title><![CDATA[제목입니다3]]></title>
<content><![CDATA[내용입니다3.]]></content>
</item>

</list>

java에서 xml을 파싱 할 때 Xpath를 이용하면 Dom 트리의 노드를 쉽게 검색이 가능하다.

파싱을 해보기 위해 임의의 xml을 하나 생성했다.

<list> 안에 <item>이 반복되고 그 안에 <title>과 <content> 각각 들어 있다.

XPath를 이용한 xml 파싱 방법

public LinkedList<Map<String, Object>> xmlLoarder() throws Exception {
    log.info("xmlLoarder start");
    DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
    domFactory.setNamespaceAware(true);
    DocumentBuilder builder = domFactory.newDocumentBuilder();

    String file_path = "<xml 파일 경로>";
    log.info("file_path : " + file_path);
    File file = new File(file_path);

    LinkedList<Map<String, Object>> xmllist = new LinkedList<Map<String, Object>>();

    if (file.exists()){
       Document doc = builder.parse(file);
       XPath xpath = XPathFactory.newInstance().newXPath();
       NodeList nodeCnt = (NodeList) xpath.evaluate("/list/item", doc, XPathConstants.NODESET);
       try {
          for (int i = 0; i < nodeCnt.getLength(); i++) {

             Node nNode = nodeCnt.item(i);
             HashMap<String, Object> mapper = new HashMap<String, Object>();

             if (nNode.getNodeType() == Node.ELEMENT_NODE) {
                Element eElement = (Element) nNode;
                mapper.put("title"  , eElement.getElementsByTagName("title").item(0).getTextContent());
                log.info("# title :"+ eElement.getElementsByTagName("title").item(0).getTextContent());
                mapper.put("content"  , eElement.getElementsByTagName("content").item(0).getTextContent());
             }
             xmllist.add(mapper);
          }
          return xmllist;
       } catch (Exception e){
          e.printStackTrace();
          return xmllist;
       }
    }else{
       return xmllist;
    }
}

1. DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); factory를 생성한다.

2. DocumentBuilder builder = domFactory.newDocumentBuilder(); factory를 이용해 builder를 생성한다.

3. NodeList nodeCnt = (NodeList) xpath.evaluate("/list/item", doc, XPathConstants.NODESET); XPath 객체를 생성하고 문법을 이용해 해당 node 리스트를 가져온다.

4. hashMap을 하나 생성하고 가져온 node 리스트를 반복문을 이용해  hashMap에 담는다.

5. 담은 hashMap 묶음은 배열형 map에 다시 담아준다.

 

@RequestMapping(value = "/xmlParse")
public String home(Model model) throws Exception {
    log.info("TestController xmlParse");

    LinkedList<Map<String, Object>> list =  xmlLoadService.xmlLoarder();
    model.addAttribute("list",list);
    return "xmlParse";
}

컨트롤러를 하나 만들고 가져온 리스트를 model에 담았다.

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%@ page trimDirectiveWhitespaces="true" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html>
<body>
<h1>xml파스</h1>
<table>
<c:forEach var="list" items="${list}" varStatus="status">
<tr>
    <td>${list.title}</td>
    <td>${list.content}</td>
</tr>
</c:forEach>
</table>
</body>
</html>

jsp를 하나 만들고 model에 담은 데이타를 이용해 테이블로 만들어 뿌려줬다.

주소를 호출해보면 xml 파싱해 데이터를 가져오는 것을 확인해 볼 수 있다.