본문 바로가기
Back-end/JAVA & Spring

자바 XML 처리 - DOM 파서(2) XML 생성 및 조작, xPath로 검색하기

by 꼬바리 2021. 6. 22.

 

DOM 파서로
XML 생성 및 조작하기

DOM 트리에 새로운 요소와 속성을 추가하거나 반대로 트리로부터 요소 및 속성을 삭제할 수도 있습니다.

▶ 노드를 생성하기 위한 메서드(Document 객체의 팩토리 메서드)

메소드 설명
Element createElement(String tagName) Element 객체를 생성
Attr createAttribute(String name) Att 객체를 생성
Text createTextNode(data) Text 객체를 생성
Comment createComment(data) Comment 객체를 생성
CDATASection createCDATASection(data)
CDATASection 객체를 생성

▶ 노드의 추가, 삭제를 하기 위한 메서드(Node 인터페이스의 메서드)

메소드 설명
Node appendChild(Node newChild) newChild를 자식 노드의 끝에 추가
Node removeChild(Node oldChild) oldChild를 자식 노드에서 삭제
Node insertBefore(Node newChild, Node oldChild)    oldChild 앞에 newChild를 삽입
Node replaceChild(Node newChild, Node oldChild) oldChild를 newChild로 교체
void setNodeValue(String nodeValue) 노드의 값(텍스트 노드의 경우는 텍스트, 주석 노드의 경우는 주석 내용)을 설정
void setTextContent(String textContent) 이 노드의 텍스트를 설정

새로운 XML 문서를 작성하고 조작해 봅시다.

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

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

import org.w3c.dom.Document;
import org.w3c.dom.Element;

public class DOMParser {
	public static void main(String[] args) throws ParserConfigurationException, IOException, TransformerException{
		// XML 문서 파싱
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder documentBuilder = factory.newDocumentBuilder();
		
		// 새로운 XML 생성! //
		// 새로운 Document 객체 생성
		Document document = documentBuilder.newDocument();
		
		// root 생성
		Element root = document.createElement("class");
		// root 속성 설정
		root.setAttribute("name", "how to use xml parser");
		
		// 자식 노드 생성
		Element teacher = document.createElement("teacher");
		teacher.setAttribute("name", "t1");
		// 텍스트 설정
		teacher.setTextContent("선생님입니다.");
		
		Element teacher2 = document.createElement("teacher");
		teacher2.setAttribute("name", "t2");
		// 텍스트 설정
		teacher2.setTextContent("선생님입니다.");
		
		Element teacher3 = document.createElement("teacher");
		teacher3.setAttribute("name", "t3");
		// 텍스트 설정
		teacher3.setTextContent("선생님입니다.");
		
		// 자식 요소 추가
		document.appendChild(root);
		root.appendChild(teacher);
		root.appendChild(teacher2);
		root.appendChild(teacher3);
		
		// XML 문자열로 변환하기! //
		ByteArrayOutputStream out = new ByteArrayOutputStream();
		
		DOMSource source = new DOMSource(document);
		StreamResult result = new StreamResult(out);
		
		TransformerFactory transFactory = TransformerFactory.newInstance();
		Transformer transformer = transFactory.newTransformer();
		
		// 출력 시 문자코드: UTF-8
		transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
		// 들여 쓰기 있음
		transformer.setOutputProperty(OutputKeys.INDENT, "yes");
		transformer.transform(source, result);
		
		System.out.println(new String(out.toByteArray(), StandardCharsets.UTF_8));
	}
}


실행 결과


DOM 파서로
XML을 XPath에서 검색하기

XPath를 사용하면 DOM 트리의 임의의 노드를 쉽게 검색할 수 있습니다.
XPath XML 문서를 검색하기 위한 쿼리 언어입니다.
예를 들어, XML 문서 내에서 name 속성 값이 "s1"인 student 요소를 검색하는 XPath는 다음과 같습니다.

//student[@name='s1']

다음은 DOM 트리를 XPath를 사용해 검색하는 예제입니다.

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class DOMParser {
	public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException{
		// XML 문서 파싱
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder documentBuilder = factory.newDocumentBuilder();
		Document document = documentBuilder.parse("sample.xml");
		
		XPathFactory xPathFactory = XPathFactory.newInstance();
		XPath xpath = xPathFactory.newXPath();
		
		// XPath를 컴파일
		XPathExpression expr = xpath.compile("//student");
		XPathExpression expr2 = xpath.compile("//student[@name='s2']");
		// XPath에서 XML 문서를 검색
		Object result = expr.evaluate(document, XPathConstants.NODESET);
		Object result2 = expr2.evaluate(document, XPathConstants.NODESET);
		
		NodeList nodes = (NodeList)result;
		for(int i = 0; i < nodes.getLength(); i++){
			Element element = (Element)nodes.item(i);
			System.out.println("att1: " + element.getAttribute("name"));
		}
		
		nodes = (NodeList)result2;
		for(int i = 0; i < nodes.getLength(); i++){
			Element element = (Element)nodes.item(i);
			System.out.println("att2: " + element.getAttribute("name"));
		}
	}
}


실행 결과

expr은 student 요소를 모두 찾는 식이고,
expr2는 name 속성 값이 "s2"인 student 요소를 찾는 식입니다.

evaluate() 메서드로 XML 문서에 대해 검색하며, 반환값은 NodeList형입니다.

XPath는 선택하는 요소 이름을 /로 구분하여 지정합니다.
속성을 지정하는 경우는 "@속성명"으로 지정합니다.
아래는 자주 사용하는 XPath입니다.

예시 설명
student 현재 노드 아래의 student 요소
./student 현재 노드 아래의 student 요소
/student    root 노드 아래의 student 요소
//student 트리 내의 모든 student 요소
student/* student 요소 아래의 모든 노드
student/@name student 요소의 name 속성
student[@name='s1'] name 속성이 's1'인 student 요소
student[starts-with(@name,'s1')] name 속성이 's1'로 시작하는 student 요소
//student[text()='abc'] 텍스트가 'abc'인 student 요소

[출처] 자바 XML 처리 - DOM 파서(2) XML 생성 및 조작, xPath로 검색하기|작성자 예비개발자

728x90
반응형

댓글