자바 XML 해상도
20528 단어 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.DefaultHandler
ContentHandler 인터페이스의 기본 구현 을 제공 합 니 다.우 리 는 이 종 류 를 확장 하여 자신의 처리 프로그램 을 만 들 수 있 습 니 다.이것 을 확장 하 는 것 을 권장 합 니 다.왜냐하면 우 리 는 아주 적은 방법 으로 만 실현 할 수 있 기 때 문 입 니 다.이러한 확장 은 우리 의 코드 를 더욱 선명 하 게 하고 유지 하기 쉽게 할 것 이다.우 리 는 여전히 같은 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