자바 XML 해상도

20528 단어 XML 해석
작업 중 에 우 리 는 xml 를 사용 할 수 있 습 니 다.예 를 들 어 자바 의 설정 파일 이나 하드웨어 를 바탕 으로 하 는 인터페이스 통신 은 보통 json 이 아니 라 xml 형식 입 니 다.그러면 조작 을 잘 하기 위해 우 리 는 xml 파일 형식 을 우리 가 필요 로 하 는 실체 대상 으로 바 꿔 야 합 니 다.그러면 xml 대상 을 어떻게 효율적으로 우리 의 실체 대상 으로 해석 합 니까?
현재 자바 에서 유행 하 는 xml 해상도 기 는 네 가지 가 있 습 니 다.
1.DOM 해석 기
2.SAX 해석 기
3.StAX 해상도 기
4.JAXB 해상도 기  (여 기 는 잠시 시험 하지 않 고 사용 하기에 상대 적 으로 복잡 하 다)
물론 위의 네 가 지 를 제외 하고 github 또는 다른 오픈 소스 플랫폼 에 도 오픈 소스 xml 분석 플러그 인 이 많 습 니 다.여 기 는 주로 코드 를 결합 하여 이 네 가지 해석 기의 사용 을 설명 한다.
DOM 해상도
DOM 해상도 기 는 가장 배우 기 쉬 운 자바 xml 해상도 기 입 니 다.DOM 해상도 기 는 XML 파일 을 메모리 에 불 러 옵 니 다.노드 별로 옮 겨 다 니 며 XML 을 분석 할 수 있 습 니 다.DOM Parser 는 작은 파일 에 적용 되 지만 파일 크기 가 증가 할 때 실행 속도 가 느 리 고 더 많은 메모 리 를 소모 합 니 다.
테스트 코드 는 다음 과 같 습 니 다:
employee.xml 테스트 파일 만 들 기:


    
        Pankaj
        544
        Java Developer
        Male
    
    
        Lisa
        35
        CSS Developer
        Female
    

DOMParse 클래스 는 다음 과 같 습 니 다:
public class DOMParse {
    //DOM Parser     XML  ,        XML        ,     XML    。    XML  ,     SAX Parser。
    public static void main(String[] args) throws Exception {
        String filePath = "D:/spring-boot/xml-demo/src/main/java/com/example/xmldemo/XMLHandler/employee.xml";
        File xmlFile = new File(filePath);
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder;
        try {
            dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(xmlFile);
            doc.getDocumentElement().normalize();
            System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
            NodeList nodeList = doc.getElementsByTagName("Employee");
            //now XML is loaded as Document in memory, lets convert it to Object List
            List empList = new ArrayList();
            for (int i = 0; i < nodeList.getLength(); i++) {
                empList.add(getEmployee(nodeList.item(i)));
            }
            //lets print Employee list information
            for (Employee emp : empList) {
                System.out.println(emp.toString());
            }
        } catch (SAXException | ParserConfigurationException | IOException e1) {
            e1.printStackTrace();
        }

    }


    private static Employee getEmployee(Node node) {
        //XMLReaderDOM domReader = new XMLReaderDOM();
        Employee emp = new Employee();
        if (node.getNodeType() == Node.ELEMENT_NODE) {
            Element element = (Element) node;
            emp.setName(getTagValue("name", element));
            emp.setAge(Integer.parseInt(getTagValue("age", element)));
            emp.setGender(getTagValue("gender", element));
            emp.setRole(getTagValue("role", element));
        }

        return emp;
    }


    private static String getTagValue(String tag, Element element) {
        NodeList nodeList = element.getElementsByTagName(tag).item(0).getChildNodes();
        Node node = (Node) nodeList.item(0);
        return node.getNodeValue();
    }

}

출력 결과:
Root element :Employees
Employee:: Name=Pankaj Age=544 Gender=Male Role=Java Developer
Employee:: Name=Lisa Age=35 Gender=Female Role=CSS Developer

SAX 해석 기
자바 SAX 해상도 기 는 XML 문 서 를 해석 하 는 API 를 제공 합 니 다.SAX 해상도 기 는 전체 XML 을 메모리 에 불 러 오고 순서대로 xml 문 서 를 읽 지 않 기 때문에 DOM 해상도 기와 다르다.이것 은 이벤트 기반 의 해상도 입 니 다.우 리 는 XML 파일 을 분석 하기 위해 Handler 클래스 를 실현 해 야 합 니 다.대형 XML 파일 의 경우 DOM Parser 보다 시간 과 메모리 사용 이 우수 합 니 다.javax.xml.parsers.SAXParser이벤트 처리 프로그램 으로 XML 문 서 를 해석 하 는 방법 을 제공 합 니 다.이러한 구현XMLReader인 터 페 이 스 를 제공 하고 버 전 을 다시 불 러 오 는parse()방법 을 제공 합 니 다.File,InputStream,SAX InputSource 와 String URI 에서 XML 문 서 를 읽 습 니 다.
실제 해석 은 Handler 클래스 에서 이 루어 집 니 다.XML 문 서 를 처리 하기 위해 서 는 자신의 처리 프로그램 클래스 를 만들어 야 합 니 다.우 리 는 자신의 처리 프로그램 클래스 를 만 들 기 위해org.xml.sax.ContentHandler인 터 페 이 스 를 실현 해 야 한다.이 인 터 페 이 스 는 어떤 사건 이 발생 했 을 때 알림 을 받 는 리 셋 방법 을 포함 하고 있 습 니 다.예 를 들 어 StartDocument,EndDocument,StartElement,EndElement,CharacterData 등 이다.org.xml.sax.helpers.DefaultHandlerContentHandler 인터페이스의 기본 구현 을 제공 합 니 다.우 리 는 이 종 류 를 확장 하여 자신의 처리 프로그램 을 만 들 수 있 습 니 다.이것 을 확장 하 는 것 을 권장 합 니 다.왜냐하면 우 리 는 아주 적은 방법 으로 만 실현 할 수 있 기 때 문 입 니 다.이러한 확장 은 우리 의 코드 를 더욱 선명 하 게 하고 유지 하기 쉽게 할 것 이다.
우 리 는 여전히 같은 employee.xml 파일 을 사용 합 니 다.
우리 만 의 Handler 대상 EmployeeXMLHandler 만 들 기:
public class EmployeeXMLHandler extends DefaultHandler {

    //List to hold Employees object
    private List empList = null;
    private Employee emp = null;


    //getter method for employee list
    public List getEmpList() {
        return empList;
    }

    boolean bAge = false;
    boolean bName = false;
    boolean bGender = false;
    boolean bRole = false;

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes)
            throws SAXException {

        if (qName.equalsIgnoreCase("Employee")) {
            //create a new Employee and put it in Map
            //initialize Employee object and set id attribute
            emp = new Employee();
            //initialize list
            if (empList == null)
                empList = new ArrayList<>();
        } else if (qName.equalsIgnoreCase("name")) {
            //set boolean values for fields, will be used in setting Employee variables
            bName = true;
        } else if (qName.equalsIgnoreCase("age")) {
            bAge = true;
        } else if (qName.equalsIgnoreCase("gender")) {
            bGender = true;
        } else if (qName.equalsIgnoreCase("role")) {
            bRole = true;
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if (qName.equalsIgnoreCase("Employee")) {
            //add Employee object to list
            empList.add(emp);
        }
    }

    @Override
    public void characters(char ch[], int start, int length) throws SAXException {

        if (bAge) {
            //age element, set Employee age
            emp.setAge(Integer.parseInt(new String(ch, start, length)));
            bAge = false;
        } else if (bName) {
            emp.setName(new String(ch, start, length));
            bName = false;
        } else if (bRole) {
            emp.setRole(new String(ch, start, length));
            bRole = false;
        } else if (bGender) {
            emp.setGender(new String(ch, start, length));
            bGender = false;
        }
    }
}

 
테스트 클래스 XMLparserSAX:
public class XMLParserSAX {

    public static void main(String[] args) {
        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
        try {
            SAXParser saxParser = saxParserFactory.newSAXParser();
            EmployeeXMLHandler handler = new EmployeeXMLHandler();
            saxParser.parse(new File("D:/spring-boot/xml-demo/src/main/java/com/example/xmldemo/XMLHandler/employee.xml"), handler);
            //Get Employees list
            List empList = handler.getEmpList();
            //print employee information
            for(Employee emp : empList)
                System.out.println(emp);
        } catch (ParserConfigurationException  | IOException | org.xml.sax.SAXException e) {
            e.printStackTrace();
        }
    }
}

출력 결과:
Employee:: Name=Pankaj Age=544 Gender=Male Role=Java Developer
Employee:: Name=Lisa Age=35 Gender=Female Role=CSS Developer

덮어 쓸 SAX 해상도 방법
다시 쓰 는 중요 한 방법 은startElement(),endElement()characters()이다.SAXParser문 서 를 분석 하기 시 작 했 습 니 다.start 요 소 를 찾 았 을 때startElement()호출 방법 입 니 다.표지 요소 에 사용 할 불 변 수 를 설정 하기 위해 서 이 방법 을 다시 씁 니 다.
Employee start 요 소 를 찾 을 때마다 이 방법 으로 새로운 Employee 대상 을 만 듭 니 다.Employee Object 를 설정 하기 위해 id 속성 을 읽 는 방법 을 검사 합 니 다.  id필드.characters()SAXParser 가 요소 에서 문자 데 이 터 를 찾 을 때 호출 하 는 방법 입 니 다.우 리 는 불 필드 를 사용 하여 값 을 Employee 대상 에서 필드 를 수정 하 는 것 으로 설정 합 니 다.
endElement()는 직원 들 이 요소 태그 목록 을 끝 낼 때마다 우리 Employee 대상 에 추 가 된 위치 입 니 다.SAXParserFactory공장 방법 을 제공 하여SAXParser인 스 턴 스 를 얻 습 니 다.우 리 는 File 대상 을 MyHandler 인 스 턴 스 와 함께 parse 방법 으로 리 셋 사건 을 처리 할 것 입 니 다.
SAX Parser 는 처음에는 혼 란 스 러 웠 지만 대형 XML 문 서 를 처리 하고 있다 면 DOM Parser 보다 더 효과 적 인 XML 읽 기 방법 을 제공 합 니 다.이것 이 자바 의 SAX Parser 입 니 다.
 
StAX Java XML 해상도 기
XML 에 사용 되 는 자바 스 트 리밍 API(Java StAX)는 자바 에서 XML 을 처리 하 는 실현 을 제공 합 니 다.StAX 는 두 개의 API 를 포함 합 니 다- 커서 기반 API 와 교체 기 기반 API.
 교체 기반 API
우 리 는 여전히 위의 employee.xml 파일 을 이용 하여 테스트 를 한다.
 
StaxXML Reader 클래스 만 들 기:
public class StaxXMLReader {

    public static void main(String[] args) {
        String fileName = "D:/spring-boot/xml-demo/src/main/java/com/example/xmldemo/XMLHandler/employee.xml";
        List empList = parseXML(fileName);
        for(Employee emp : empList){
            System.out.println(emp.toString());
        }
    }

    private static List parseXML(String fileName) {
        List empList = new ArrayList<>();
        Employee emp = null;
        XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
        try {
            XMLEventReader xmlEventReader = xmlInputFactory.createXMLEventReader(new FileInputStream(fileName));
            while(xmlEventReader.hasNext()){
                XMLEvent xmlEvent = xmlEventReader.nextEvent();
                if (xmlEvent.isStartElement()){
                    StartElement startElement = xmlEvent.asStartElement();
                    if(startElement.getName().getLocalPart().equals("Employee")){
                        emp = new Employee();
                        //Get the 'id' attribute from Employee element
                        Attribute idAttr = startElement.getAttributeByName(new QName("id"));
                        /*if(idAttr != null){
                            emp.setId(Integer.parseInt(idAttr.getValue()));
                        }*/
                    }
                    //set the other varibles from xml elements
                    else if(startElement.getName().getLocalPart().equals("age")){
                        xmlEvent = xmlEventReader.nextEvent();
                    //        ,  age              
                        if(xmlEvent.isEndElement()) {
                            emp.setAge(Integer.parseInt("1000"));
                        }
                        else
                        {
                            emp.setAge(Integer.parseInt(xmlEvent.asCharacters().getData()));
                        }

                    }else if(startElement.getName().getLocalPart().equals("name")){
                        xmlEvent = xmlEventReader.nextEvent();
                        emp.setName(xmlEvent.asCharacters().getData());
                    }else if(startElement.getName().getLocalPart().equals("gender")){
                        xmlEvent = xmlEventReader.nextEvent();
                        emp.setGender(xmlEvent.asCharacters().getData());
                    }else if(startElement.getName().getLocalPart().equals("role")){
                        xmlEvent = xmlEventReader.nextEvent();
                        emp.setRole(xmlEvent.asCharacters().getData());
                    }
                }
                //if Employee end element is reached, add employee object to list
                if(xmlEvent.isEndElement()){
                    EndElement endElement = xmlEvent.asEndElement();
                    System.out.println("       "+endElement.getName().getLocalPart());
                    if(endElement.getName().getLocalPart().equals("Employee")){
                        empList.add(emp);
                    }
                }
            }

        } catch (FileNotFoundException | XMLStreamException e) {
            e.printStackTrace();
        }
        return empList;
    }
}

 
 
커서 기반 API
StAX XML Parser 를 사용 할 때 XML 파일 을 읽 기 위해 서 는XMLInputFactory를 만들어 야 합 니 다.그리고 커서 기반 API 를 선택 하기 위해 서 파일 을 읽 기 위해 서XMLStreamReader대상 을 만 들 수 있 습 니 다. 。XMLStreamReader next()방법 은 다음 해석 이 벤트 를 가 져 오고 이벤트 형식 에 따라 int 값 을 되 돌려 줍 니 다.흔히 볼 수 있 는 이벤트 유형 은 Start Document,Start Element,Characters,End Element 와 End Document 를 포함한다.XMLStreamConstants이벤트 유형 에 따라 사건 을 처리 할 수 있 는 int 상수 가 포함 되 어 있 습 니 다.
테스트 클래스 StaxXML Reader 2
public class StaxXMLReader2
{
    private static boolean bName;
    private static boolean bAge;
    private static boolean bGender;
    private static boolean bRole;

    public static void main(String[] args) {
        String fileName = "D:/spring-boot/xml-demo/src/main/java/com/example/xmldemo/XMLHandler/employee.xml";
        List empList = parseXML(fileName);
        for(Employee emp : empList){
            System.out.println(emp.toString());
        }
    }

    private static List parseXML(String fileName) {
        List empList = new ArrayList<>();
        Employee emp = null;
        XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
        try {
            XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(new FileInputStream(fileName));
            int event = xmlStreamReader.getEventType();
            while(true){
                switch(event) {
                    case XMLStreamConstants.START_ELEMENT:
                        if(xmlStreamReader.getLocalName().equals("Employee")){
                            emp = new Employee();
                           // emp.setId(Integer.parseInt(xmlStreamReader.getAttributeValue(0)));
                        }else if(xmlStreamReader.getLocalName().equals("name")){
                            bName=true;
                        }else if(xmlStreamReader.getLocalName().equals("age")){
                            bAge=true;
                        }else if(xmlStreamReader.getLocalName().equals("role")){
                            bRole=true;
                        }else if(xmlStreamReader.getLocalName().equals("gender")){
                            bGender=true;
                        }
                        break;
                    case XMLStreamConstants.CHARACTERS:
                        if(bName){
                            emp.setName(xmlStreamReader.getText());
                            bName=false;
                        }else if(bAge){
                            emp.setAge(Integer.parseInt(xmlStreamReader.getText()));
                            bAge=false;
                        }else if(bGender){
                            emp.setGender(xmlStreamReader.getText());
                            bGender=false;
                        }else if(bRole){
                            emp.setRole(xmlStreamReader.getText());
                            bRole=false;
                        }
                        break;
                    case XMLStreamConstants.END_ELEMENT:
                        if(xmlStreamReader.getLocalName().equals("Employee")){
                            empList.add(emp);
                        }
                        break;
                }
                if (!xmlStreamReader.hasNext())
                    break;

                event = xmlStreamReader.next();
            }

        } catch (FileNotFoundException | XMLStreamException e) {
            e.printStackTrace();
        }
        return empList;
    }
}

실행 결과:
Employee:: Name=Pankaj Age=544 Gender=Male Role=Java Developer
Employee:: Name=Lisa Age=35 Gender=Female Role=CSS Developer

 
 
 
 
Java XML Parser - JDOM
JDOM 은 XML 문 서 를 쉽게 읽 고 편집 하 며 작성 할 수 있 는 훌륭 한 자바 XML 해상도 API 를 제공 합 니 다.JDOM 은 SAX Parser,DOM Parser,STAX Event Parser 와 STAX Stream Parser 에서 바 텀 을 선택 하여 구현 할 수 있 는 포장 류 를 제공 합 니 다.
maven 의존 도 추가:
    
        
            org.jdom
            jdom2
            2.0.6
        

 
테스트 클래스 JDOMXMLReader:
public class JDOMXMLReader {
    //  JDOM          SAX   DOM STAX Parser,                     。
    public static void main(String[] args) {
        final String fileName = "D:/spring-boot/xml-demo/src/main/java/com/example/xmldemo/XMLHandler/employee.xml";
        org.jdom2.Document jdomDoc;
        try {
            //we can create JDOM Document from DOM, SAX and STAX Parser Builder classes
            jdomDoc = useDOMParser(fileName);
           // jdomDoc = useSAXParser(fileName);
          //  jdomDoc = useSTAXParser(fileName,"stream");
            Element root = jdomDoc.getRootElement();
            List empListElements = root.getChildren("Employee");
            List empList = new ArrayList<>();
            for (Element empElement : empListElements) {
                Employee emp = new Employee();
               // emp.setId(Integer.parseInt(empElement.getAttributeValue("id")));
                emp.setAge(Integer.parseInt(empElement.getChildText("age")));
                emp.setName(empElement.getChildText("name"));
                emp.setRole(empElement.getChildText("role"));
                emp.setGender(empElement.getChildText("gender"));
                empList.add(emp);
            }
            //lets print Employees list information
            for (Employee emp : empList)
                System.out.println(emp);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    //Get JDOM document from DOM Parser
    private static org.jdom2.Document useDOMParser(String fileName)
            throws ParserConfigurationException, SAXException, IOException {
        //creating DOM Document
        DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder dBuilder;
        dBuilder = dbFactory.newDocumentBuilder();
        Document doc = dBuilder.parse(new File(fileName));
        DOMBuilder domBuilder = new DOMBuilder();
        return domBuilder.build(doc);

    }

    //Get JDOM document from SAX Parser
    private static org.jdom2.Document useSAXParser(String fileName) throws JDOMException,
            IOException {
        SAXBuilder saxBuilder = new SAXBuilder();
        return saxBuilder.build(new File(fileName));
    }

    //Get JDOM Document from STAX Stream Parser or STAX Event Parser
    private static org.jdom2.Document useSTAXParser(String fileName, String type) throws FileNotFoundException, XMLStreamException, JDOMException{
        if(type.equalsIgnoreCase("stream")){
            StAXStreamBuilder staxBuilder = new StAXStreamBuilder();
            XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
            XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(new FileInputStream(fileName));
            return staxBuilder.build(xmlStreamReader);
        }
        StAXEventBuilder staxBuilder = new StAXEventBuilder();
        XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance();
        XMLEventReader xmlEventReader = xmlInputFactory.createXMLEventReader(new FileInputStream(fileName));
        return staxBuilder.build(xmlEventReader);

    }
}

JDOM 을 사용 하 는 장점 은 SAX 에서 DOM 에서 STAX Parser 로 쉽게 전환 할 수 있다 는 것 이다.우 리 는 관련 실현 인 터 페 이 스 를 제공 하여 클 라 이언 트 응용 프로그램 이 선택 할 수 있 도록 할 수 있다.
 
 
전체 테스트 코드 주소:https://github.com/bo-zhang-1/Xml-Parser
 
 
 
 

좋은 웹페이지 즐겨찾기