Skip to main content

DOM XML Parsing, dBuilder.parse(), normalize()

Image result for java dom parser


DOM을 이용하여 XML instance의 일부 데이터 목록을 parsing 해 보았다.

1
2
3
4
5
6
7
8
9
10
public class Ex_xml_parsing {
    public static void main(String[] args) {
        try {
            File xmlFile = new File("D:/Workspace/_JAVA/Ex_xml_parsing/src/test.xml");            
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); // instance 생성            
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); // builder 생성            
            Document doc = dBuilder.parse(xmlFile); // xml 파일을 dom 객체로 파싱
cs

dBuilder.parse(xmlFile)

DocumentBuilder.parse(File f): Parse the content of the given InputStream as an XML document and return a new DOM Document object. An IllegalArgumentException is thrown if the InputStream is null. throws SAXException, IOException

(XML 문서 컨텐트를 parse해서 DOM 문서 객체로 리턴한다.)

1
doc.getDocumentElement().normalize(); // 파싱한 파일 normalize
cs

doc.getDocumentElement().normalize(): Puts all Text nodes in the full depth of the sub-tree underneath this Node where only structure (e.g., elements, comments, processing instructions, CDATA sections, and entity references) separates Text nodes, i.e., there are neither adjacent Text nodes nor empty Text nodes.

This basically means that the following XML element

<foo>hello
wor
ld</foo>
could be represented like this in a denormalized node:

Element foo
    Text node: ""
    Text node: "Hello "
    Text node: "wor"
    Text node: "ld"
When normalized, the node will look like this

Element foo
    Text node: "Hello world"

(<foo>hello
wor
ld</foo>
이런 형태의 코드를 denormalize된 노드로 표현하면:

Element foo
    Text node: ""
    Text node: "Hello "
    Text node: "wor"
    Text node: "ld"
normalize하면

Element foo
    Text node: "Hello world"
이렇게 된다.)


- 전체 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;
import java.io.*;
/*
DOM XML Parser Example
Ref - http://www.mkyong.com/java/how-to-read-xml-file-in-java-dom-parser/
*/
public class Ex_xml_parsing {
    public static void main(String[] args) {
        try {
            File xmlFile = new File("D:/Workspace/_JAVA/Ex_xml_parsing/src/test.xml");            
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); // instance 생성            
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); // builder 생성            
            Document doc = dBuilder.parse(xmlFile); // xml 파일을 dom 객체로 파싱
            doc.getDocumentElement().normalize(); // 파싱한 파일 normalize
            // 루트 element(최상위 노드)의 이름 출력
            System.out.println("Root element :" + doc.getDocumentElement().getNodeName());             
            System.out.println("\n");           
            // staff라는 이름을 가진 element를 모두 찾아 NodeList로 리턴 
            NodeList nList = doc.getElementsByTagName("staff"); 
            // 리스트의 길이 만큼 출력            for (int temp = 0; temp < nList.getLength(); temp++) {
                Node nNode = nList.item(temp); // NodeList.item(int index): return the indexth item in the collection
                // getNodeType(): A code representing the type of the underlying object, as defined above
                if (nNode.getNodeType() == Node.ELEMENT_NODE) {                                                             
                    // ELEMENT_NODE: The node is an Element.                    
                    Element eElement = (Element) nNode;
                    // getElementsByTagName(String name): Returns a NodeList of all descendant 
                    // Elements with a given tag name, in document order
                    // getTextContent(): This attribute returns the text content of this node and its descendants.                    
                    System.out.println("Staff id : " + eElement.getAttribute("id"));                     
                    System.out.println("First Name : " + eElement.getElementsByTagName("firstname").item(0).getTextContent()); 
                    System.out.println("Last Name : " + eElement.getElementsByTagName("lastname").item(0).getTextContent());                    
                    System.out.println("Nick Name : " + eElement.getElementsByTagName("nickname").item(0).getTextContent());                    
                    System.out.println("Salary : " + eElement.getElementsByTagName("salary").item(0).getTextContent());                }
            }
        } catch (Exception e) {
            e.printStackTrace();        
          }
    }
}
cs

- 출력값

Root element :company


Staff id : 1001
First Name : yong
Last Name : mook kim
Nick Name : mkyong
Salary : 100000
Staff id : 2001
First Name : low
Last Name : yin fong
Nick Name : fong fong
Salary : 200000


- test.xml

<?xml version="1.0" encoding="utf-8"?>
<company>
    <staff id="1001">
        <firstname>yong</firstname>
        <firstname>kong</firstname>
        <lastname>mook kim</lastname>
        <nickname>mkyong</nickname>
        <salary>100000</salary>
    </staff>
    <staff id="2001">
        <firstname>low</firstname>
        <lastname>yin fong</lastname>
        <nickname>fong fong</nickname>
        <salary>200000</salary>
    </staff>
</company>

Comments

Popular posts from this blog

Solution: react-native-maps showsUserLocation 동작 안함 해결 방법

react-navive-maps를 이용해서 지도를 구현하고 있는데 내 위치로 가기 버튼이 보이질 않았다. First of all, a reminder: for the button to be visible, some criteria are needed (OK in the OP): showsUserLocation  must be set  true  because the default is  false showsMyLocationButton  must stay  true , as is the default The issue is in a race condition between two asynchronous events: onMapReady and onLayout (noted Ready and Layout, for short, below). The decision to draw the button or not is done at the time of the Layout, and the setting of UserLocation can't be done before the Ready of the map (a handle to it is needed). Unfortunately, usually, at launch, the Layout arrives  before  the Ready. 위 글을 참조해보면 showUserLocation과 showsMyLocationButton이 모두 true로 설정되어 있어야 하고,  문제는 onMapReady과 onLayout의 동기화 문제라고한다. 버튼을 그릴지 말지가 Layout이 다 마무리 되는 시점에 결정되고  유저의 위치는 맵이 다 준비 되어야만 작동을 하는데 일반적으로 맵이 다 준비되기 전에 Layout이 먼저 그려져 버려서 버튼이 안보이는 거라고 한다. 밑에 댓글들을 쭉...

리눅스 멀티부팅 삽질기(Linux Mint Cinnamon 18.2 Sonya, Ubuntu 16.04.3 LTS)

설치를 시도한 리눅스 종류 및 버전 Linux Mint Cinnamon 18.2, Sonya Ubuntu 16.04.3 LTS 사실은 전에도 이번 노트북을 사자마자 우분투를 멀티부팅으로 돌려 보려고 시도 했었다. 하지만 그때는 시간도 없었고 하루 이틀정도 노가다 하다가 결국 실패. 그 후에는 리눅스를 가끔 가상머신으로만 사용해서 굳이 멀티부팅으로 할 필요성을 못 느꼈었다. 그런데 요즘 파이썬을 많이 쓰기 시작하면서 가상 머신이 굉장히 답답하다는 생각을 하던중, 최근에 다른 친구가 리눅스를 듀얼로 돌리는 것을 보고 갑자기 삘 받아서 듀얼 부팅 설치 시작! 처음엔 이제 우분투보다 민트가 대세라고 해서 민트를 설치했다. 리눅스 민트 홈페이지에서 최신 버전인  18.2 시나몬을 다운  받고 Rufus 프로그램을 사용하여 부팅 USB 를 만들었다. 만드는 방법은 다른 블로그에도 많으니 잘 모르시면 검색해보시라. 그리고 나서 BIOS로 들어가 최근 윈도우에서 멀티부팅을 할 때 문제가 된다는 Fast Boot, Secure Boot를 모두 비활성화  한 뒤, 윈도우 디스크 관리에서 볼륨 축소 를 이용하여 대략 38GB정도(Swap용: 8GB, /용: 30GB)로 파티션을 만든 뒤 설치를 진행했다. 그런데 역시나 같은 우분투 계열이라 그런지 전에 겪었던 똑같은 문제가 발생했다. 그 문제는 바로 처음 설치할 때 '민트의 M자 심볼 마크와 점 다섯개가 있는 화면'에서 더 이상 진행되지 않고 화면이 멈추는 현상이었다. 지난번에도 이 문제를 해결하려고 재설치를 몇 번을 반복하고, USB가 고장났나 싶어 여기저기서 안쓰는 USB를 찾아서 시도해 보았었는데 결국 안되서 포기했었다. 그때보다 나의 검색 능력이 증가했는지 이번에는 어렵게 해결 방법을 찾을 수 있었다. 바로 Nvidia의 그래픽 카드 문제라는 것! 좀 더 자세히 말하자면 nouveau라고 하는 오픈...