Apache Xerces - คู่มือฉบับย่อ

XML คืออะไร?

XML เป็นภาษาข้อความธรรมดาซึ่งออกแบบมาเพื่อจัดเก็บและขนส่งข้อมูลในรูปแบบข้อความธรรมดา ย่อมาจาก Extensible Markup Language ต่อไปนี้เป็นคุณสมบัติเด่นบางประการของ XML

  • XML เป็นภาษามาร์กอัป

  • XML เป็นภาษาที่ใช้แท็กเช่น HTML

  • แท็ก XML ไม่ได้กำหนดไว้ล่วงหน้าเช่น HTML

  • คุณสามารถกำหนดแท็กของคุณเองซึ่งเป็นสาเหตุที่เรียกว่าภาษาที่ขยายได้

  • แท็ก XML ได้รับการออกแบบให้สามารถอธิบายได้ด้วยตนเอง ..

  • XML เป็นคำแนะนำ W3C สำหรับการจัดเก็บข้อมูลและการขนส่ง

ตัวอย่าง

<?xml version = "1.0"?>
<Class>
   <Name>First</Name>
   <Sections>
      
      <Section>
         <Name>A</Name>
         <Students>
            <Student>Rohan</Student>
            <Student>Mohan</Student>
            <Student>Sohan</Student>
            <Student>Lalit</Student>
            <Student>Vinay</Student>
         </Students>
      </Section>
      
      <Section>
         <Name>B</Name>
         <Students>
            <Student>Robert</Student>
            <Student>Julie</Student>
            <Student>Kalie</Student>
            <Student>Michael</Student>				
         </Students>
      </Section>
      
   </Sections>
</Class>

ข้อดี

ต่อไปนี้เป็นข้อดีของ XML -

  • Technology agnostic- เป็นข้อความธรรมดา XML จึงเป็นอิสระจากเทคโนโลยี สามารถใช้เทคโนโลยีใดก็ได้เพื่อการจัดเก็บข้อมูลและการส่งข้อมูล

  • Human readable- XML ​​ใช้รูปแบบข้อความธรรมดา มนุษย์สามารถอ่านและเข้าใจได้

  • Extensible - ใน XML สามารถสร้างและใช้แท็กที่กำหนดเองได้อย่างง่ายดาย

  • Allow Validation - การใช้โครงสร้าง XSD, DTD และ XML สามารถตรวจสอบได้อย่างง่ายดาย

ข้อเสีย

ต่อไปนี้เป็นข้อเสียของการใช้ XML -

  • Redundant Syntax - โดยปกติไฟล์ XML จะมีคำศัพท์ซ้ำ ๆ กันมากมาย

  • Verbose - เนื่องจากเป็นภาษา verbose ขนาดไฟล์ XML จะเพิ่มค่าใช้จ่ายในการส่งและจัดเก็บข้อมูล

บทนี้จะนำคุณเข้าสู่กระบวนการตั้งค่า Apache Xerces บนระบบที่ใช้ Windows และ Linux Apache Xerces สามารถติดตั้งและรวมเข้ากับสภาพแวดล้อม Java ปัจจุบันของคุณได้อย่างง่ายดายโดยทำตามขั้นตอนง่ายๆไม่กี่ขั้นตอนโดยไม่ต้องมีขั้นตอนการตั้งค่าที่ซับซ้อน จำเป็นต้องมีการดูแลระบบผู้ใช้ขณะติดตั้ง

ความต้องการของระบบ

JDK Java SE 2 JDK 1.5 ขึ้นไป
หน่วยความจำ RAM 1 GB (แนะนำ)
พื้นที่ดิสก์ ไม่มีข้อกำหนดขั้นต่ำ
เวอร์ชันระบบปฏิบัติการ Windows XP ขึ้นไปลินุกซ์

ให้เราดำเนินการตามขั้นตอนเพื่อติดตั้ง Apache Xerces

ขั้นตอนที่ 1: ตรวจสอบการติดตั้ง Java ของคุณ

ก่อนอื่นคุณต้องติดตั้ง Java Software Development Kit (SDK) ในระบบของคุณ ในการตรวจสอบสิ่งนี้ให้ดำเนินการคำสั่งใด ๆ จากสองคำสั่งทั้งนี้ขึ้นอยู่กับแพลตฟอร์มที่คุณกำลังทำงานอยู่

หากการติดตั้ง Java สำเร็จจะแสดงเวอร์ชันปัจจุบันและข้อกำหนดของการติดตั้ง Java ของคุณ ตัวอย่างผลลัพธ์จะได้รับในตารางต่อไปนี้

แพลตฟอร์ม คำสั่ง ตัวอย่างผลลัพธ์
Windows เปิด Command Console และพิมพ์: java -version เวอร์ชัน Java "1.7.0_60" Java (TM) SE Run Time Environment (build 1.7.0_60-b19) Java Hotspot (TM) 64-bit Server VM (build 24.60b09, mixed mode)
ลินุกซ์ เปิดเทอร์มินัลคำสั่งและพิมพ์: $ java -version เวอร์ชัน Java "1.7.0_25" เปิด JDK Runtime Environment (rhel-2.3.10.4.el6_4-x86_64) เปิด JDK 64-Bit Server VM (build 23.7-b01, mixed mode)
  • เราถือว่าผู้อ่านบทช่วยสอนนี้ติดตั้ง Java SDK เวอร์ชัน 1.7.0_60 ในระบบของตน

  • ในกรณีที่คุณไม่มี Java SDK ให้ดาวน์โหลดเวอร์ชันปัจจุบันจากไฟล์ https://www.oracle.com/technetwork/java/javase/downloads/index.html และติดตั้ง

ขั้นตอนที่ 2: ตั้งค่าสภาพแวดล้อม Java ของคุณ

ตั้งค่าตัวแปรสภาพแวดล้อม JAVA_HOME ให้ชี้ไปยังตำแหน่งไดเร็กทอรีฐานที่ติดตั้ง Java บนเครื่องของคุณ ตัวอย่างเช่น,

ซีเนียร์ แพลตฟอร์มและคำอธิบาย
1

Windows

ตั้งค่า JAVA_HOME เป็น C: \ ProgramFiles \ java \ jdk1.7.0_60

2

Linux

ส่งออก JAVA_HOME = / usr / local / java-current

ผนวกพา ธ แบบเต็มของตำแหน่งคอมไพเลอร์ Java เข้ากับ System Path

ซีเนียร์ แพลตฟอร์มและคำอธิบาย
1

Windows

ต่อท้าย String "C: \ Program Files \ Java \ jdk1.7.0_60 \ bin" ต่อท้ายตัวแปรระบบ PATH

2

Linux

ส่งออกเส้นทาง = $ PATH: $ JAVA_HOME / bin /

เรียกใช้คำสั่งเวอร์ชัน java จากพรอมต์คำสั่งตามที่อธิบายไว้ข้างต้น

ขั้นตอนที่ 3: ติดตั้ง Apache Xerces Library

ดาวน์โหลด Apache Xerces เวอร์ชันล่าสุดจาก https://xerces.apache.org/mirrors.cgi"และคลายซิปเนื้อหาไปยังโฟลเดอร์ที่สามารถเชื่อมโยงไลบรารีที่ต้องการกับโปรแกรม Java ของคุณได้ สมมติว่าไฟล์ถูกรวบรวมไว้ในโฟลเดอร์ xerces-2_11_0 บนไดรฟ์ C

เพิ่มเส้นทางที่สมบูรณ์ของห้าไหตามที่ไฮไลต์ในภาพด้านบนไปยัง CLASSPATH

ซีเนียร์ แพลตฟอร์มและคำอธิบาย
1

Windows

ต่อท้ายสตริงต่อไปนี้ต่อท้ายตัวแปรผู้ใช้ CLASSPATH -

C: \ xerces-2_11_0 \ resolver.jar;

C: \ xerces-2_11_0 \ serializer.jar;

C: \ xerces-2_11_0 \ xercesImpl.jar;

C: \ xerces-2_11_0 \ xercesSamples.jar;

C: \ xerces-2_11_0 \ xml-apis.jar;

2

Linux

ส่งออก CLASSPATH = $ CLASSPATH -

/usr/share/xerces-2_11_0\resolver.jar;

/usr/share/xerces-2_11_0\serializer.jar;

/usr/share/xerces-2_11_0\xercesImpl.jar;

/usr/share/xerces-2_11_0\xercesSamples.jar;

/usr/share/xerces-2_11_0\xml-apis.jar;

Apache Xerces2 คืออะไร

Xerces2 เป็นโปรเซสเซอร์ที่ใช้ Java และมีอินเทอร์เฟซและการใช้งานมาตรฐานสำหรับการแยกวิเคราะห์ XML ตามมาตรฐาน API -

  • Document Object Model (DOM) ระดับ 3

  • Simple API สำหรับ XML (SAX) 2.0.2

  • Streaming API สำหรับ XML (StAX) 1.0 Event API

  • Java API สำหรับการประมวลผล XML (JAXP) 1.4

XML Parsing คืออะไร?

การแยกวิเคราะห์ XML หมายถึงการดำเนินการผ่านเอกสาร XML เพื่อเข้าถึงข้อมูลหรือแก้ไขข้อมูลด้วยวิธีใดวิธีหนึ่ง

XML Parser คืออะไร

XML Parser จัดเตรียมวิธีการเข้าถึงหรือแก้ไขข้อมูลที่มีอยู่ในเอกสาร XML Java มีตัวเลือกมากมายในการแยกวิเคราะห์เอกสาร XML ต่อไปนี้เป็นตัวแยกวิเคราะห์ประเภทต่างๆซึ่งมักใช้ในการแยกวิเคราะห์เอกสาร XML

  • Dom Parser - แยกวิเคราะห์เอกสารโดยการโหลดเนื้อหาทั้งหมดของเอกสารและสร้างแผนผังลำดับชั้นที่สมบูรณ์ในหน่วยความจำ

  • SAX Parser- แยกวิเคราะห์เอกสารตามทริกเกอร์ตามเหตุการณ์ ไม่โหลดเอกสารฉบับสมบูรณ์ลงในหน่วยความจำ

  • StAX Parser - แยกวิเคราะห์เอกสารในลักษณะเดียวกับตัวแยกวิเคราะห์ SAX แต่มีประสิทธิภาพมากขึ้น

ตอนนี้เราจะอธิบายรายละเอียดแต่ละตัวแยกวิเคราะห์โดยใช้ไลบรารี Apache Xerces ในบทต่อ ๆ ไปของเรา

Document Object Model เป็นคำแนะนำอย่างเป็นทางการของ World Wide Web Consortium (W3C) กำหนดอินเทอร์เฟซที่ช่วยให้โปรแกรมสามารถเข้าถึงและอัปเดตสไตล์โครงสร้างและเนื้อหาของเอกสาร XML ตัวแยกวิเคราะห์ XML ที่สนับสนุน DOM ใช้อินเทอร์เฟซนั้น

ใช้เมื่อไหร่?

คุณควรใช้ตัวแยกวิเคราะห์ DOM เมื่อ -

  • คุณจำเป็นต้องรู้มากเกี่ยวกับโครงสร้างของเอกสาร

  • คุณต้องย้ายส่วนต่างๆของเอกสารไปรอบ ๆ (คุณอาจต้องการจัดเรียงองค์ประกอบบางอย่างเป็นต้น)

  • คุณจำเป็นต้องใช้ข้อมูลในเอกสารมากกว่าหนึ่งครั้ง

สิ่งที่คุณได้รับ?

เมื่อคุณแยกวิเคราะห์เอกสาร XML ด้วยตัวแยกวิเคราะห์ DOM คุณจะได้รับโครงสร้างแผนผังที่มีองค์ประกอบทั้งหมดของเอกสารของคุณกลับคืนมา DOM มีฟังก์ชันมากมายที่คุณสามารถใช้เพื่อตรวจสอบเนื้อหาและโครงสร้างของเอกสาร

ข้อดี

DOM เป็นอินเทอร์เฟซทั่วไปสำหรับจัดการโครงสร้างเอกสาร หนึ่งในเป้าหมายการออกแบบคือโค้ด Java ที่เขียนขึ้นสำหรับตัวแยกวิเคราะห์ที่สอดคล้องกับ DOM หนึ่งตัวควรทำงานบนตัวแยกวิเคราะห์ที่สอดคล้องกับ DOM โดยไม่มีการเปลี่ยนแปลง

อินเทอร์เฟซ DOM

DOM กำหนดอินเตอร์เฟส Java หลายรายการ นี่คืออินเทอร์เฟซที่พบบ่อยที่สุด -

  • Node - ประเภทข้อมูลพื้นฐานของ DOM

  • Element - วัตถุส่วนใหญ่ที่คุณจะจัดการคือองค์ประกอบ

  • Attr - แสดงถึงคุณลักษณะขององค์ประกอบ

  • Text - เนื้อหาจริงขององค์ประกอบหรือ Attr

  • Document- แสดงถึงเอกสาร XML ทั้งหมด วัตถุเอกสารมักเรียกว่าโครงสร้าง DOM

วิธี DOM ทั่วไป

เมื่อคุณทำงานกับ DOM มีหลายวิธีที่ใช้บ่อย -

  • Document.getDocumentElement() - ส่งคืนองค์ประกอบรากของเอกสาร

  • Node.getFirstChild() - ส่งคืนลูกคนแรกของโหนดที่กำหนด

  • Node.getLastChild() - ส่งคืนลูกสุดท้ายของโหนดที่กำหนด

  • Node.getNextSibling() - วิธีการเหล่านี้ส่งคืนพี่น้องถัดไปของโหนดที่กำหนด

  • Node.getPreviousSibling() - วิธีการเหล่านี้ส่งคืนพี่น้องก่อนหน้าของโหนดที่กำหนด

  • Node.getAttribute(attrName) - สำหรับ Node ที่ระบุให้ส่งคืนแอตทริบิวต์พร้อมชื่อที่ร้องขอ

ขั้นตอนในการใช้ DOM

ต่อไปนี้เป็นขั้นตอนที่ใช้ในขณะแยกวิเคราะห์เอกสารโดยใช้ DOM Parser

  • นำเข้าแพ็คเกจที่เกี่ยวข้องกับ XML

  • สร้าง DocumentBuilder

  • สร้างเอกสารจากไฟล์หรือสตรีม

  • แยกองค์ประกอบราก

  • ตรวจสอบคุณลักษณะ

  • ตรวจสอบองค์ประกอบย่อย

นำเข้าแพ็คเกจที่เกี่ยวข้องกับ XML

import org.w3c.dom.*;
import javax.xml.parsers.*;
import java.io.*;

สร้าง DocumentBuilder

DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();

สร้างเอกสารจากไฟล์หรือสตรีม

StringBuilder xmlStringBuilder = new StringBuilder();
xmlStringBuilder.append("<?xml version = "1.0"?> <class> </class>");
ByteArrayInputStream input =  new ByteArrayInputStream(
   xmlStringBuilder.toString().getBytes("UTF-8"));
Document doc = builder.parse(input);

แยกองค์ประกอบราก

Element root = document.getDocumentElement();

ตรวจสอบคุณลักษณะ

//returns specific attribute
getAttribute("attributeName"); 
//returns a Map (table) of names/values
getAttributes();

ตรวจสอบองค์ประกอบย่อย

//returns a list of subelements of specified name
getElementsByTagName("subelementName"); 
//returns a list of all child nodes
getChildNodes();

Demo Example

นี่คือไฟล์ xml อินพุตที่เราต้องแยกวิเคราะห์ -

<?xml version = "1.0"?>
<class>
   
   <student rollno = "393">
      <firstname>Dinkar</firstname>
      <lastname>Kad</lastname>
      <nickname>Dinkar</nickname>
      <marks>85</marks>
   </student>
   
   <student rollno = "493">
      <firstname>Vineet</firstname>
      <lastname>Gupta</lastname>
      <nickname>Vinni</nickname>
      <marks>95</marks>
   </student>
   
   <student rollno = "593">
      <firstname>Jasvir</firstname>
      <lastname>Singh</lastname>
      <nickname>Jazz</nickname>
      <marks>90</marks>
   </student>
</class>

ตัวอย่างการสาธิต

DomParserDemo.java

package com.tutorialspoint.xml;

import java.io.File;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;

public class DomParserDemo {
   public static void main(String[] args){

      try {	
         File inputFile = new File("input.txt");
         DocumentBuilderFactory dbFactory 
            = DocumentBuilderFactory.newInstance();
         DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
         Document doc = dBuilder.parse(inputFile);
         doc.getDocumentElement().normalize();
         
         System.out.println("Root element :" 
            + doc.getDocumentElement().getNodeName());
         NodeList nList = doc.getElementsByTagName("student");
         
         System.out.println("----------------------------");
         for (int temp = 0; temp < nList.getLength(); temp++) {
            Node nNode = nList.item(temp);
            
            System.out.println("\nCurrent Element :" 
               + nNode.getNodeName());
            if (nNode.getNodeType() == Node.ELEMENT_NODE) {
               Element eElement = (Element) nNode;
               
               System.out.println("Student roll no : " 
                  + eElement.getAttribute("rollno"));
               
               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("Marks : " 
               + eElement
                  .getElementsByTagName("marks")
                  .item(0)
                  .getTextContent());
            }
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

โปรแกรมข้างต้นจะสร้างผลลัพธ์ต่อไปนี้ -

Root element :class
----------------------------

Current Element :student
Student roll no : 393
First Name : Dinkar
Last Name : Kad
Nick Name : Dinkar
Marks : 85

Current Element :student
Student roll no : 493
First Name : Vineet
Last Name : Gupta
Nick Name : Vinni
Marks : 95

Current Element :student
Student roll no : 593
First Name : Jasvir
Last Name : Singh
Nick Name : Jazz
Marks : 90

ตัวอย่างการสาธิต

นี่คือไฟล์ xml อินพุตที่เราต้องการค้นหา -

<?xml version = "1.0"?>
<cars>
   <supercars company = "Ferrari">
      <carname type = "formula one">Ferarri 101</carname>
      <carname type = "sports car">Ferarri 201</carname>
      <carname type = "sports car">Ferarri 301</carname>
   </supercars>
   
   <supercars company = "Lamborgini">
      <carname>Lamborgini 001</carname>
      <carname>Lamborgini 002</carname>
      <carname>Lamborgini 003</carname>
   </supercars>
   
   <luxurycars company = "Benteley">
      <carname>Benteley 1</carname>
      <carname>Benteley 2</carname>
      <carname>Benteley 3</carname>
   </luxurycars>
</cars>

ตัวอย่างการสาธิต

QueryXmlFileDemo.java

package com.tutorialspoint.xml;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import java.io.File;

public class QueryXmlFileDemo {
	
   public static void main(String argv[]) {
 
      try {
         File inputFile = new File("input.txt");
         DocumentBuilderFactory dbFactory = 
            DocumentBuilderFactory.newInstance();
         DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
         Document doc = dBuilder.parse(inputFile);
         doc.getDocumentElement().normalize();
         System.out.print("Root element: ");
         System.out.println(doc.getDocumentElement().getNodeName());
         NodeList nList = doc.getElementsByTagName("supercars");
         System.out.println("----------------------------");
         for (int temp = 0; temp < nList.getLength(); temp++) {
            Node nNode = nList.item(temp);
            System.out.println("\nCurrent Element :");
            System.out.print(nNode.getNodeName());
            if (nNode.getNodeType() == Node.ELEMENT_NODE) {
               Element eElement = (Element) nNode;
               System.out.print("company : ");
               System.out.println(eElement.getAttribute("company"));
               NodeList carNameList = 
                  eElement.getElementsByTagName("carname");
               for (int count = 0; 
                  count < carNameList.getLength(); count++) {	 
                  Node node1 = carNameList.item(count);
                  if (node1.getNodeType() ==
                     node1.ELEMENT_NODE) {
                     Element car = (Element) node1;
                     System.out.print("car name : ");
                     System.out.println(car.getTextContent());
                     System.out.print("car type : ");
                     System.out.println(car.getAttribute("type"));
                  }
               }
            }
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

โปรแกรมข้างต้นจะสร้างผลลัพธ์ต่อไปนี้ -

Root element :cars
----------------------------

Current Element :supercars
company : Ferrari
car name : Ferarri 101
car type : formula one
car name : Ferarri 201
car type : sports car
car name : Ferarri 301
car type : sports car

Current Element :supercars
company : Lamborgini
car name : Lamborgini 001
car type : 
car name : Lamborgini 002
car type : 
car name : Lamborgini 003
car type :

ตัวอย่างการสาธิต

นี่คือ XML ที่เราต้องสร้าง -

<?xml version = "1.0" encoding = "UTF-8" standalone = "no"?>
<cars><supercars company = "Ferrari">
   <carname type = "formula one">Ferrari 101</carname>
   <carname type = "sports">Ferrari 202</carname>
</supercars></cars>

ตัวอย่างการสาธิต

CreateXmlFileDemo.java

package com.tutorialspoint.xml;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.io.File;

public class CreateXmlFileDemo {
	
   public static void main(String argv[]) {

      try {
         DocumentBuilderFactory dbFactory =
         DocumentBuilderFactory.newInstance();
         DocumentBuilder dBuilder = 
            dbFactory.newDocumentBuilder();
         Document doc = dBuilder.newDocument();
         
         // root element
         Element rootElement = doc.createElement("cars");
         doc.appendChild(rootElement);

         //  supercars element
         Element supercar = doc.createElement("supercars");
         rootElement.appendChild(supercar);

         // setting attribute to element
         Attr attr = doc.createAttribute("company");
         attr.setValue("Ferrari");
         supercar.setAttributeNode(attr);

         // carname element
         Element carname = doc.createElement("carname");
         Attr attrType = doc.createAttribute("type");
         attrType.setValue("formula one");
         carname.setAttributeNode(attrType);
         carname.appendChild(
         doc.createTextNode("Ferrari 101"));
         supercar.appendChild(carname);

         Element carname1 = doc.createElement("carname");
         Attr attrType1 = doc.createAttribute("type");
         attrType1.setValue("sports");
         carname1.setAttributeNode(attrType1);
         carname1.appendChild(
         doc.createTextNode("Ferrari 202"));
         supercar.appendChild(carname1);

         // write the content into xml file
         TransformerFactory transformerFactory =
         TransformerFactory.newInstance();
         Transformer transformer =
         transformerFactory.newTransformer();
         DOMSource source = new DOMSource(doc);
         StreamResult result =
         new StreamResult(new File("C:\\cars.xml"));
         transformer.transform(source, result);
         
         // Output to console for testing
         StreamResult consoleResult =
         new StreamResult(System.out);
         transformer.transform(source, consoleResult);
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

โปรแกรมข้างต้นจะสร้างผลลัพธ์ต่อไปนี้ -

<?xml version = "1.0" encoding = "UTF-8" standalone = "no"?>
<cars><supercars company = "Ferrari">
<carname type = "formula one">Ferrari 101</carname>
<carname type = "sports">Ferrari 202</carname>
</supercars></cars>

ตัวอย่างการสาธิต

นี่คือไฟล์ xml อินพุตที่เราต้องแก้ไข -

<?xml version = "1.0" encoding = "UTF-8" standalone = "no"?>
<cars>
   <supercars company = "Ferrari">
      <carname type = "formula one">Ferrari 101</carname>
      <carname type = "sports">Ferrari 202</carname>
   </supercars>
   
   <luxurycars company = "Benteley">
      <carname>Benteley 1</carname>
      <carname>Benteley 2</carname>
      <carname>Benteley 3</carname>
   </luxurycars>
</cars>

ตัวอย่างการสาธิต

ModifyXmlFileDemo.java

package com.tutorialspoint.xml;

import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
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;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class ModifyXmlFileDemo {

public static void main(String argv[]) {

   try {
      File inputFile = new File("input.txt"); 	    	
      DocumentBuilderFactory docFactory =
      DocumentBuilderFactory.newInstance();
      DocumentBuilder docBuilder = 
      docFactory.newDocumentBuilder();
      Document doc = docBuilder.parse(inputFile);
      Node cars = doc.getFirstChild();
      Node supercar = doc.getElementsByTagName("supercars").item(0);
      
      // update supercar attribute
      NamedNodeMap attr = supercar.getAttributes();
      Node nodeAttr = attr.getNamedItem("company");
      nodeAttr.setTextContent("Lamborigini");

      // loop the supercar child node
      NodeList list = supercar.getChildNodes();
      for (int temp = 0; temp < list.getLength(); temp++) {
         Node node = list.item(temp);
         if (node.getNodeType() == Node.ELEMENT_NODE) {
            Element eElement = (Element) node;
            if ("carname".equals(eElement.getNodeName())){
               if("Ferrari 101".equals(eElement.getTextContent())){
                  eElement.setTextContent("Lamborigini 001");
               }
            if("Ferrari 202".equals(eElement.getTextContent()))
               eElement.setTextContent("Lamborigini 002");
            }
         }
      }
      
      NodeList childNodes = cars.getChildNodes();
      for(int count = 0; count < childNodes.getLength(); count++){
         Node node = childNodes.item(count);
         if("luxurycars".equals(node.getNodeName()))
            cars.removeChild(node);
         }
         
         // write the content on console
         TransformerFactory transformerFactory = 
         TransformerFactory.newInstance();
         Transformer transformer = transformerFactory.newTransformer();
         DOMSource source = new DOMSource(doc);
         System.out.println("-----------Modified File-----------");
         StreamResult consoleResult = new StreamResult(System.out);
         transformer.transform(source, consoleResult);
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
}

โปรแกรมข้างต้นจะสร้างผลลัพธ์ต่อไปนี้ -

-----------Modified File-----------
<?xml version = "1.0" encoding = "UTF-8" standalone = "no"?>
<cars>
<supercars company = "Lamborigini">
<carname type = "formula one">Lamborigini 001</carname>
<carname type = "sports">Lamborigini 002</carname>
</supercars></cars>

SAX (Simple API สำหรับ XML) คือตัวแยกวิเคราะห์ตามเหตุการณ์สำหรับเอกสาร xml ไม่เหมือนกับตัวแยกวิเคราะห์ DOM ตัวแยกวิเคราะห์ SAX จะไม่สร้างโครงสร้างการแยกวิเคราะห์ SAX เป็นอินเทอร์เฟซการสตรีมสำหรับ XML ซึ่งหมายความว่าแอปพลิเคชันที่ใช้ SAX ได้รับการแจ้งเตือนเหตุการณ์เกี่ยวกับเอกสาร XML ที่กำลังดำเนินการ - องค์ประกอบและแอตทริบิวต์ในแต่ละครั้งตามลำดับโดยเริ่มจากด้านบนของเอกสารและลงท้ายด้วยการปิด องค์ประกอบราก

  • อ่านเอกสาร XML จากบนลงล่างโดยรับรู้โทเค็นที่ประกอบขึ้นเป็นเอกสาร XML ที่มีรูปแบบดี

  • โทเค็นจะถูกประมวลผลตามลำดับเดียวกับที่ปรากฏในเอกสาร

  • รายงานโปรแกรมแอปพลิเคชันลักษณะของโทเค็นที่ตัวแยกวิเคราะห์พบเมื่อเกิดขึ้น

  • โปรแกรมแอปพลิเคชันมีตัวจัดการ "เหตุการณ์" ที่ต้องลงทะเบียนกับโปรแกรมแยกวิเคราะห์

  • เมื่อมีการระบุโทเค็นเมธอดการโทรกลับในตัวจัดการจะถูกเรียกด้วยข้อมูลที่เกี่ยวข้อง

ใช้เมื่อไหร่?

คุณควรใช้โปรแกรมแยกวิเคราะห์ SAX เมื่อ -

  • คุณสามารถประมวลผลเอกสาร XML ในลักษณะเชิงเส้นจากบนลงล่าง

  • เอกสารไม่ซ้อนกันลึก

  • คุณกำลังประมวลผลเอกสาร XML ที่มีขนาดใหญ่มากซึ่งเป็นโครงสร้าง DOM ซึ่งจะใช้หน่วยความจำมาก การใช้งาน DOM โดยทั่วไปจะใช้หน่วยความจำสิบไบต์เพื่อแทน XML หนึ่งไบต์

  • ปัญหาที่ต้องแก้ไขเกี่ยวข้องกับเอกสาร XML เพียงบางส่วนเท่านั้น

  • ข้อมูลจะพร้อมใช้งานทันทีที่เห็นโดยตัวแยกวิเคราะห์ดังนั้น SAX จึงทำงานได้ดีสำหรับเอกสาร XML ที่มาถึงผ่านสตรีม

ข้อเสียของ SAX

  • เราไม่มีการเข้าถึงเอกสาร XML โดยสุ่มเนื่องจากมีการประมวลผลในลักษณะส่งต่อเท่านั้น

  • หากคุณต้องการติดตามข้อมูลที่ตัวแยกวิเคราะห์เห็นหรือเปลี่ยนลำดับของรายการคุณต้องเขียนโค้ดและจัดเก็บข้อมูลด้วยตัวคุณเอง

อินเทอร์เฟซ ContentHandler

อินเทอร์เฟซนี้ระบุวิธีการเรียกกลับที่ตัวแยกวิเคราะห์ SAX ใช้เพื่อแจ้งโปรแกรมแอปพลิเคชันเกี่ยวกับส่วนประกอบของเอกสาร XML ที่ได้เห็น

  • void startDocument() - เรียกที่จุดเริ่มต้นของเอกสาร

  • void endDocument() - เรียกที่จุดเริ่มต้นของเอกสาร

  • void startElement(String uri, String localName, String qName, Attributes atts) - เรียกที่จุดเริ่มต้นขององค์ประกอบ

  • void endElement(String uri, String localName,String qName) - เรียกว่าเมื่อสิ้นสุดองค์ประกอบ

  • void characters(char[] ch, int start, int length) - เรียกเมื่อพบข้อมูลอักขระ

  • void ignorableWhitespace( char[] ch, int start, int length) - เรียกเมื่อ DTD ปรากฏและพบช่องว่างที่ไม่สามารถใช้งานได้

  • void processingInstruction(String target, String data) - เรียกเมื่อรู้จักคำสั่งการประมวลผล

  • void setDocumentLocator(Locator locator)) - จัดเตรียม Locator ที่สามารถใช้เพื่อระบุตำแหน่งในเอกสาร

  • void skippedEntity(String name) - เรียกเมื่อพบเอนทิตีที่ไม่ได้รับการแก้ไข

  • void startPrefixMapping(String prefix, String uri) - เรียกเมื่อมีการกำหนดการแมปเนมสเปซใหม่

  • void endPrefixMapping(String prefix) - เรียกเมื่อนิยามเนมสเปซสิ้นสุดขอบเขต

อินเทอร์เฟซแอตทริบิวต์

อินเทอร์เฟซนี้ระบุวิธีการประมวลผลแอตทริบิวต์ที่เชื่อมต่อกับองค์ประกอบ

  • int getLength() - ส่งกลับจำนวนแอตทริบิวต์

  • String getQName(int index)

  • String getValue(int index)

  • String getValue(String qname)

ตัวอย่างการสาธิต

นี่คือไฟล์ xml อินพุตที่เราต้องแยกวิเคราะห์ -

<?xml version = "1.0"?>
<class>
   <student rollno = "393">
      <firstname>Dinkar</firstname>
      <lastname>Kad</lastname>
      <nickname>Dinkar</nickname>
      <marks>85</marks>
   </student>
   
   <student rollno = "493">
      <firstname>Vineet</firstname>
      <lastname>Gupta</lastname>
      <nickname>Vinni</nickname>
      <marks>95</marks>
   </student>
   
   <student rollno = "593">
      <firstname>Jasvir</firstname>
      <lastname>Singh</lastname>
      <nickname>Jazz</nickname>
      <marks>90</marks>
   </student>
</class>

UserHandler.java

package com.tutorialspoint.xml;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class UserHandler extends DefaultHandler {

   boolean bFirstName = false;
   boolean bLastName = false;
   boolean bNickName = false;
   boolean bMarks = false;

   @Override
   public void startElement(String uri, 
   String localName, String qName, Attributes attributes) throws SAXException {
      if (qName.equalsIgnoreCase("student")) {
         String rollNo = attributes.getValue("rollno");
         System.out.println("Roll No : " + rollNo);
      } else if (qName.equalsIgnoreCase("firstname")) {
         bFirstName = true;
      } else if (qName.equalsIgnoreCase("lastname")) {
         bLastName = true;
      } else if (qName.equalsIgnoreCase("nickname")) {
         bNickName = true;
      } else if (qName.equalsIgnoreCase("marks")) {
         bMarks = true;
      }
   }

   @Override
   public void endElement(String uri, 
   String localName, String qName) throws SAXException {
      if (qName.equalsIgnoreCase("student")) {
         System.out.println("End Element :" + qName);
      }
   }

   @Override
   public void characters(char ch[], int start, int length) throws SAXException {
      if (bFirstName) {
         System.out.println("First Name: " + new String(ch, start, length));
         bFirstName = false;
      } else if (bLastName) {
         System.out.println("Last Name: " + new String(ch, start, length));
         bLastName = false;
      } else if (bNickName) {
         System.out.println("Nick Name: " + new String(ch, start, length));
         bNickName = false;
      } else if (bMarks) {
         System.out.println("Marks: " + new String(ch, start, length));
         bMarks = false;
      }
   }
}

SAXParserDemo.java

package com.tutorialspoint.xml;

import java.io.File;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SAXParserDemo {
   public static void main(String[] args){

      try {	
         File inputFile = new File("input.txt");
         SAXParserFactory factory = SAXParserFactory.newInstance();
         SAXParser saxParser = factory.newSAXParser();
         UserHandler userhandler = new UserHandler();
         saxParser.parse(inputFile, userhandler);     
      } catch (Exception e) {
         e.printStackTrace();
      }
   }   
}

class UserHandler extends DefaultHandler {

   boolean bFirstName = false;
   boolean bLastName = false;
   boolean bNickName = false;
   boolean bMarks = false;

   @Override
   public void startElement(String uri, 
      String localName, String qName, Attributes attributes) throws SAXException {
      if (qName.equalsIgnoreCase("student")) {
         String rollNo = attributes.getValue("rollno");
         System.out.println("Roll No : " + rollNo);
      } else if (qName.equalsIgnoreCase("firstname")) {
         bFirstName = true;
      } else if (qName.equalsIgnoreCase("lastname")) {
         bLastName = true;
      } else if (qName.equalsIgnoreCase("nickname")) {
         bNickName = true;
      } else if (qName.equalsIgnoreCase("marks")) {
         bMarks = true;
      }
   }

   @Override
   public void endElement(String uri, 
      String localName, String qName) throws SAXException {
      if (qName.equalsIgnoreCase("student")) {
         System.out.println("End Element :" + qName);
      }
   }

   @Override
   public void characters(char ch[], int start, int length) throws SAXException {
      if (bFirstName) {
         System.out.println("First Name: " + new String(ch, start, length));
         bFirstName = false;
      } else if (bLastName) {
         System.out.println("Last Name: " + new String(ch, start, length));
         bLastName = false;
      } else if (bNickName) {
         System.out.println("Nick Name: " + new String(ch, start, length));
         bNickName = false;
      } else if (bMarks) {
         System.out.println("Marks: " + new String(ch, start, length));
         bMarks = false;
      }
   }
}

โปรแกรมข้างต้นจะสร้างผลลัพธ์ต่อไปนี้ -

Roll No : 393
First Name: Dinkar
Last Name: Kad
Nick Name: Dinkar
Marks: 85
End Element :student
Roll No : 493
First Name: Vineet
Last Name: Gupta
Nick Name: Vinni
Marks: 95
End Element :student
Roll No : 593
First Name: Jasvir
Last Name: Singh
Nick Name: Jazz
Marks: 90
End Element :student

ตัวอย่างการสาธิต

นี่คือไฟล์ข้อความอินพุตที่เราต้องการเพื่อค้นหาหมายเลขม้วน: 393 -

<?xml version = "1.0"?>
<class>
   <student rollno = "393">
      <firstname>Dinkar</firstname>
      <lastname>Kad</lastname>
      <nickname>Dinkar</nickname>
      <marks>85</marks>
   </student>
   
   <student rollno = "493">
      <firstname>Vineet</firstname>
      <lastname>Gupta</lastname>
      <nickname>Vinni</nickname>
      <marks>95</marks>
   </student>
   
   <student rollno = "593">
      <firstname>Jasvir</firstname>
      <lastname>Singh</lastname>
      <nickname>Jazz</nickname>
      <marks>90</marks>
   </student>
</class>

UserHandler.java

package com.tutorialspoint.xml;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
 
 
public class UserHandler extends DefaultHandler {

   boolean bFirstName = false;
   boolean bLastName = false;
   boolean bNickName = false;
   boolean bMarks = false;
   String rollNo = null;

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

      if (qName.equalsIgnoreCase("student")) {
         rollNo = attributes.getValue("rollno");
      }
      if(("393").equals(rollNo) && qName.equalsIgnoreCase("student")){
         System.out.println("Start Element :" + qName);      
      }       
      if (qName.equalsIgnoreCase("firstname")) {
         bFirstName = true;
      } else if (qName.equalsIgnoreCase("lastname")) {
         bLastName = true;
      } else if (qName.equalsIgnoreCase("nickname")) {
         bNickName = true;
      } else if (qName.equalsIgnoreCase("marks")) {
         bMarks = true;
      }
   }

   @Override
   public void endElement(String uri, String localName, String qName) throws SAXException {
      if (qName.equalsIgnoreCase("student")) {
         if(("393").equals(rollNo) 
            && qName.equalsIgnoreCase("student"))
            System.out.println("End Element :" + qName);
      }
   }


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

      if (bFirstName && ("393").equals(rollNo)) {
         //age element, set Employee age
         System.out.println("First Name: " + new String(ch, start, length));
         bFirstName = false;
      } else if (bLastName && ("393").equals(rollNo)) {
         System.out.println("Last Name: " + new String(ch, start, length));
         bLastName = false;
      } else if (bNickName && ("393").equals(rollNo)) {
         System.out.println("Nick Name: " + new String(ch, start, length));
         bNickName = false;
      } else if (bMarks && ("393").equals(rollNo)) {
         System.out.println("Marks: " + new String(ch, start, length));
         bMarks = false;
      }
   }
}

SAXQueryDemo.java

package com.tutorialspoint.xml;

import java.io.File;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

public class SAXQueryDemo {
   public static void main(String[] args){

      try {	
         File inputFile = new File("input.txt");
         SAXParserFactory factory = SAXParserFactory.newInstance();
         SAXParser saxParser = factory.newSAXParser();
         UserHandler userhandler = new UserHandler();
         saxParser.parse(inputFile, userhandler);     
      } catch (Exception e) {
         e.printStackTrace();
      }
   }   
}

class UserHandler extends DefaultHandler {

   boolean bFirstName = false;
   boolean bLastName = false;
   boolean bNickName = false;
   boolean bMarks = false;
   String rollNo = null;

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

      if (qName.equalsIgnoreCase("student")) {
         rollNo = attributes.getValue("rollno");
      }
      if(("393").equals(rollNo) &&
         qName.equalsIgnoreCase("student")){
         System.out.println("Start Element :" + qName);      
      }       
      if (qName.equalsIgnoreCase("firstname")) {
         bFirstName = true;
      } else if (qName.equalsIgnoreCase("lastname")) {
         bLastName = true;
      } else if (qName.equalsIgnoreCase("nickname")) {
         bNickName = true;
      } else if (qName.equalsIgnoreCase("marks")) {
         bMarks = true;
      }
   }

   @Override
   public void endElement(String uri, 
      String localName, String qName) throws SAXException {
      if (qName.equalsIgnoreCase("student")) {
         if(("393").equals(rollNo) 
            && qName.equalsIgnoreCase("student"))
            System.out.println("End Element :" + qName);
      }
   }


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

      if (bFirstName && ("393").equals(rollNo)) {
         //age element, set Employee age
         System.out.println("First Name: " + new String(ch, start, length));
         bFirstName = false;
      } else if (bLastName && ("393").equals(rollNo)) {
         System.out.println("Last Name: " + new String(ch, start, length));
         bLastName = false;
      } else if (bNickName && ("393").equals(rollNo)) {
         System.out.println("Nick Name: " + new String(ch, start, length));
         bNickName = false;
      } else if (bMarks && ("393").equals(rollNo)) {
         System.out.println("Marks: " + new String(ch, start, length));
         bMarks = false;
      }
   }
}

โปรแกรมข้างต้นจะสร้างผลลัพธ์ต่อไปนี้ -

Start Element :student
First Name: Dinkar
Last Name: Kad
Nick Name: Dinkar
Marks: 85
End Element :student

การใช้ตัวแยกวิเคราะห์ StAX ในการสร้าง XML จะดีกว่าการใช้ตัวแยกวิเคราะห์ SAX โปรดดูส่วน Java StAX Parser สำหรับสิ่งเดียวกัน

ตัวอย่างการสาธิต

นี่คือไฟล์ xml อินพุตที่เราต้องแก้ไขโดยต่อท้าย <Result>Pass<Result/> ในตอนท้ายของ </marks> tag.

<?xml version = "1.0"?>
<class>
   <student rollno = "393">
      <firstname>Dinkar</firstname>
      <lastname>Kad</lastname>
      <nickname>Dinkar</nickname>
      <marks>85</marks>
   </student>
   
   <student rollno = "493">
      <firstname>Vineet</firstname>
      <lastname>Gupta</lastname>
      <nickname>Vinni</nickname>
      <marks>95</marks>
   </student>
   
   <student rollno = "593">
      <firstname>Jasvir</firstname>
      <lastname>Singh</lastname>
      <nickname>Jazz</nickname>
      <marks>90</marks>
   </student>
</class>

SAXModifyDemo.java

package com.tutorialspoint.xml;

import java.io.*;
import org.xml.sax.*;
import javax.xml.parsers.*;
import org.xml.sax.helpers.DefaultHandler;

public class SAXModifyDemo extends DefaultHandler {
   static String displayText[] = new String[1000];
   static int numberLines = 0;
   static String indentation = "";

   public static void main(String args[]) {

      try {	
         File inputFile = new File("input.txt");
         SAXParserFactory factory = 
         SAXParserFactory.newInstance();
         SAXModifyDemo obj = new SAXModifyDemo();
         obj.childLoop(inputFile);
         FileWriter filewriter = new FileWriter("newfile.xml");
         for(int loopIndex = 0; loopIndex < numberLines; loopIndex++){
            filewriter.write(displayText[loopIndex].toCharArray());
            filewriter.write('\n');
            System.out.println(displayText[loopIndex].toString());
         }
         filewriter.close();
      } catch (Exception e) {
         e.printStackTrace(System.err);
      }
   }

   public void childLoop(File input){
      DefaultHandler handler = this;
      SAXParserFactory factory = SAXParserFactory.newInstance();
      try {
         SAXParser saxParser = factory.newSAXParser();
         saxParser.parse(input, handler);
      } catch (Throwable t) {}
   }

   public void startDocument() {
      displayText[numberLines] = indentation;
      displayText[numberLines] += "<?xml version=\"1.0\" encoding=\""+
         "UTF-8" + "\"?>";
      numberLines++;
   }

   public void processingInstruction(String target, String data) {
      displayText[numberLines] = indentation;
      displayText[numberLines] += "<?";
      displayText[numberLines] += target;
      if (data != null && data.length() > 0) {
         displayText[numberLines] += ' ';
         displayText[numberLines] += data;
      }
      displayText[numberLines] += "?>";
      numberLines++;
   }

   public void startElement(String uri, String localName,
      String qualifiedName, Attributes attributes) {
      displayText[numberLines] = indentation;

      indentation += "    ";

      displayText[numberLines] += '<';
      displayText[numberLines] += qualifiedName;
      if (attributes != null) {
         int numberAttributes = attributes.getLength();
         for (int loopIndex = 0; loopIndex < numberAttributes;
            loopIndex++){
            displayText[numberLines] += ' ';
            displayText[numberLines] += attributes.getQName(loopIndex);
            displayText[numberLines] += "=\"";
            displayText[numberLines] += attributes.getValue(loopIndex);
            displayText[numberLines] += '"';
         }
      }
      displayText[numberLines] += '>';
      numberLines++;
   }

   public void characters(char characters[], int start, int length) {
      String characterData = (new String(characters, start, length)).trim();
      if(characterData.indexOf("\n") < 0 && characterData.length() > 0) {
         displayText[numberLines] = indentation;
         displayText[numberLines] += characterData;
         numberLines++;
      }
   }

   public void endElement(String uri, String localName, String qualifiedName) {
      indentation = indentation.substring(0, indentation.length() - 4);
      displayText[numberLines] = indentation;
      displayText[numberLines] += "</";
      displayText[numberLines] += qualifiedName;
      displayText[numberLines] += '>';
      numberLines++;

      if (qualifiedName.equals("marks")) {
         startElement("", "Result", "Result", null);
         characters("Pass".toCharArray(), 0, "Pass".length());
         endElement("", "Result", "Result");
      }
   }
}

โปรแกรมข้างต้นจะสร้างผลลัพธ์ต่อไปนี้ -

<?xml version = "1.0" encoding = "UTF-8"?>
<class>
   <student rollno = "393">
      <firstname>
         Dinkar
      </firstname>

      <lastname>
         Kad
      </lastname>

      <nickname>
         Dinkar
      </nickname>

      <marks>
         85
      </marks>

      <Result>
         Pass
      </Result>
   </student>
    
   <student rollno = "493">
      <firstname>
         Vineet
      </firstname>

      <lastname>
         Gupta
      </lastname>

      <nickname>
         Vinni
      </nickname>

      <marks>
         95
      </marks>

      <Result>
         Pass
      </Result>
   </student>
    
   <student rollno = "593">
      <firstname>
         Jasvir
      </firstname>

      <lastname>
         Singh
      </lastname>

      <nickname>
         Jazz
      </nickname>

      <marks>
        90
      </marks>

      <Result>
         Pass
      </Result>
   </student>
</class>

StAX เป็น API ที่ใช้ JAVA เพื่อแยกวิเคราะห์เอกสาร XML ในลักษณะเดียวกับที่โปรแกรมแยกวิเคราะห์ SAX ทำ แต่มีสองประเด็นหลักที่แตกต่างระหว่าง API ทั้งสอง -

  • StAX เป็น PULL API ในขณะที่ SAX เป็น PUSH API หมายความว่าในกรณีของตัวแยกวิเคราะห์ StAX แอปพลิเคชันไคลเอนต์จำเป็นต้องขอให้ตัวแยกวิเคราะห์ StAX รับข้อมูลจาก XML เมื่อใดก็ตามที่ต้องการ แต่ในกรณีของตัวแยกวิเคราะห์ SAX แอปพลิเคชันไคลเอ็นต์จะต้องได้รับข้อมูลเมื่อตัวแยกวิเคราะห์ SAX แจ้งให้แอปพลิเคชันไคลเอนต์ทราบข้อมูล สามารถใช้ได้.

  • StAX API สามารถอ่านและเขียนเอกสาร XML ใช้ SAX API xml สามารถอ่านได้เท่านั้น

ต่อไปนี้เป็นคุณสมบัติของ StAX API -

  • อ่านเอกสาร XML จากบนลงล่างโดยรับรู้โทเค็นที่ประกอบขึ้นเป็นเอกสาร XML ที่มีรูปแบบดี

  • โทเค็นจะถูกประมวลผลตามลำดับเดียวกับที่ปรากฏในเอกสาร

  • รายงานโปรแกรมแอปพลิเคชันเกี่ยวกับลักษณะของโทเค็นที่ตัวแยกวิเคราะห์พบเมื่อเกิดขึ้น

  • โปรแกรมแอปพลิเคชันให้โปรแกรมอ่าน "เหตุการณ์" ซึ่งทำหน้าที่เป็นตัววนซ้ำและวนซ้ำเหตุการณ์เพื่อรับข้อมูลที่ต้องการ เครื่องอ่านอื่นที่มีอยู่คือเครื่องอ่าน "เคอร์เซอร์" ซึ่งทำหน้าที่เป็นตัวชี้ไปยังโหนด xml

  • เนื่องจากเหตุการณ์ถูกระบุองค์ประกอบ xml สามารถเรียกดูจากอ็อบเจ็กต์เหตุการณ์และสามารถประมวลผลเพิ่มเติมได้

ใช้เมื่อไหร่?

คุณควรใช้ตัวแยกวิเคราะห์ StAX เมื่อ -

  • คุณสามารถประมวลผลเอกสาร XML ในลักษณะเชิงเส้นจากบนลงล่าง

  • เอกสารไม่ซ้อนกันลึก

  • คุณกำลังประมวลผลเอกสาร XML ที่มีขนาดใหญ่มากซึ่งโครงสร้าง DOM จะใช้หน่วยความจำมากเกินไป การใช้งาน DOM โดยทั่วไปจะใช้หน่วยความจำสิบไบต์เพื่อแทน XML หนึ่งไบต์

  • ปัญหาที่ต้องแก้ไขเกี่ยวข้องกับเอกสาร XML เพียงบางส่วนเท่านั้น

  • ข้อมูลจะพร้อมใช้งานทันทีที่เห็นโดยตัวแยกวิเคราะห์ดังนั้น StAX จึงทำงานได้ดีสำหรับเอกสาร XML ที่มาถึงผ่านสตรีม

ข้อเสียของ SAX

  • เราไม่มีการเข้าถึงเอกสาร XML แบบสุ่มเนื่องจากมีการประมวลผลในลักษณะส่งต่อเท่านั้น

  • หากคุณต้องการติดตามข้อมูลที่ตัวแยกวิเคราะห์เห็นหรือเปลี่ยนลำดับของรายการคุณต้องเขียนโค้ดและจัดเก็บข้อมูลด้วยตัวคุณเอง

คลาส XMLEventReader

คลาสนี้จัดเตรียมตัววนซ้ำของเหตุการณ์ซึ่งสามารถใช้เพื่อวนซ้ำเหตุการณ์ที่เกิดขึ้นขณะแยกวิเคราะห์เอกสาร XML

  • StartElement asStartElement() - ใช้เพื่อดึงค่าและคุณลักษณะขององค์ประกอบ

  • EndElement asEndElement() - เรียกว่าเมื่อสิ้นสุดองค์ประกอบ

  • Characters asCharacters() - สามารถใช้เพื่อรับอักขระเช่น CDATA ช่องว่าง ฯลฯ

คลาส XMLEventWriter

อินเทอร์เฟซนี้ระบุวิธีการสร้างเหตุการณ์

  • add(Event event) - เพิ่มเหตุการณ์ที่มีองค์ประกอบใน XML

คลาส XMLStreamReader

คลาสนี้จัดเตรียมตัววนซ้ำของเหตุการณ์ซึ่งสามารถใช้เพื่อวนซ้ำเหตุการณ์ที่เกิดขึ้นขณะแยกวิเคราะห์เอกสาร XML

  • int next() - ใช้เพื่อดึงข้อมูลเหตุการณ์ต่อไป

  • boolean hasNext() - ใช้เพื่อตรวจสอบเหตุการณ์เพิ่มเติมว่ามีอยู่หรือไม่

  • String getText() - ใช้เพื่อรับข้อความขององค์ประกอบ

  • String getLocalName() - ใช้เพื่อรับชื่อขององค์ประกอบ

คลาส XMLStreamWriter

อินเทอร์เฟซนี้ระบุวิธีการสร้างเหตุการณ์

  • writeStartElement(String localName) - เพิ่มองค์ประกอบเริ่มต้นของชื่อที่กำหนด

  • writeEndElement(String localName) - เพิ่มองค์ประกอบท้ายของชื่อที่กำหนด

  • writeAttribute(String localName, String value) - เขียนแอตทริบิวต์ให้กับองค์ประกอบ

ตัวอย่างการสาธิต

นี่คือไฟล์ xml อินพุตที่เราต้องแยกวิเคราะห์ -

<?xml version = "1.0"?>
<class>
   <student rollno = "393">
      <firstname>Dinkar</firstname>
      <lastname>Kad</lastname>
      <nickname>Dinkar</nickname>
      <marks>85</marks>
   </student>
   
   <student rollno = "493">
      <firstname>Vineet</firstname>
      <lastname>Gupta</lastname>
      <nickname>Vinni</nickname>
      <marks>95</marks>
   </student>
   
   <student rollno = "593">
      <firstname>Jasvir</firstname>
      <lastname>Singh</lastname>
      <nickname>Jazz</nickname>
      <marks>90</marks>
   </student>
</class>

StAXParserDemo.java

package com.tutorialspoint.xml;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Iterator;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

public class StAXParserDemo {
   public static void main(String[] args) {
      boolean bFirstName = false;
      boolean bLastName = false;
      boolean bNickName = false;
      boolean bMarks = false;
      try {
         XMLInputFactory factory = XMLInputFactory.newInstance();
         XMLEventReader eventReader =
         factory.createXMLEventReader(new FileReader("input.txt"));

         while(eventReader.hasNext()){
            XMLEvent event = eventReader.nextEvent();
            switch(event.getEventType()){
               case XMLStreamConstants.START_ELEMENT:
                  StartElement startElement = event.asStartElement();
                  String qName = startElement.getName().getLocalPart();
                  if (qName.equalsIgnoreCase("student")) {
                     System.out.println("Start Element : student");
                     Iterator<Attribute> attributes = startElement.getAttributes();
                     String rollNo = attributes.next().getValue();
                     System.out.println("Roll No : " + rollNo);
                  } else if (qName.equalsIgnoreCase("firstname")) {
                     bFirstName = true;
                  } else if (qName.equalsIgnoreCase("lastname")) {
                     bLastName = true;
                  } else if (qName.equalsIgnoreCase("nickname")) {
                     bNickName = true;
                  } else if (qName.equalsIgnoreCase("marks")) {
                     bMarks = true;
                  }				        
                  break;
               case XMLStreamConstants.CHARACTERS:
                  Characters characters = event.asCharacters();
                  if(bFirstName){
                     System.out.println("First Name: " + characters.getData());
                     bFirstName = false;
                  }
                  if(bLastName){
                     System.out.println("Last Name: " + characters.getData());
                     bLastName = false;
                  }
                  if(bNickName){
                     System.out.println("Nick Name: " + characters.getData());
                     bNickName = false;
                  }
                  if(bMarks){
                     System.out.println("Marks: " + characters.getData());
                     bMarks = false;
                  }
                  break;
               case XMLStreamConstants.END_ELEMENT:
                  EndElement endElement = event.asEndElement();
                  if(endElement.getName().getLocalPart().equalsIgnoreCase("student")){
                     System.out.println("End Element : student");
                     System.out.println();
                  }
                  break;
            }		    
         }
      } catch (FileNotFoundException e) {
         e.printStackTrace();
      } catch (XMLStreamException e) {
         e.printStackTrace();
      }
   }
}

โปรแกรมข้างต้นจะสร้างผลลัพธ์ต่อไปนี้ -

Start Element : student
Roll No : 393
First Name: Dinkar
Last Name: Kad
Nick Name: Dinkar
Marks: 85
End Element : student

Start Element : student
Roll No : 493
First Name: Vineet
Last Name: Gupta
Nick Name: Vinni
Marks: 95
End Element : student

Start Element : student
Roll No : 593
First Name: Jasvir
Last Name: Singh
Nick Name: Jazz
Marks: 90
End Element : student

ตัวอย่างการสาธิต

นี่คือไฟล์ xml อินพุตที่เราต้องแยกวิเคราะห์ -

<?xml version = "1.0"?>
<class>
   <student rollno = "393">
      <firstname>Dinkar</firstname>
      <lastname>Kad</lastname>
      <nickname>Dinkar</nickname>
      <marks>85</marks>
   </student>
   
   <student rollno = "493">
      <firstname>Vineet</firstname>
      <lastname>Gupta</lastname>
      <nickname>Vinni</nickname>
      <marks>95</marks>
   </student>
   
   <student rollno = "593">
      <firstname>Jasvir</firstname>
      <lastname>Singh</lastname>
      <nickname>Jazz</nickname>
      <marks>90</marks>
   </student>
</class>

StAXParserDemo.java

package com.tutorialspoint.xml;

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Iterator;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

public class StAXQueryDemo {
   public static void main(String[] args) {
      boolean bFirstName = false;
      boolean bLastName = false;
      boolean bNickName = false;
      boolean bMarks = false;
      boolean isRequestRollNo = false;
      try {
         XMLInputFactory factory = XMLInputFactory.newInstance();
         XMLEventReader eventReader = factory.createXMLEventReader(
            new FileReader("input.txt"));

         String requestedRollNo = "393";
         while(eventReader.hasNext()){
            XMLEvent event = eventReader.nextEvent();
            switch(event.getEventType()){
               case XMLStreamConstants.START_ELEMENT:
                  StartElement startElement = event.asStartElement();
                  String qName = startElement.getName().getLocalPart();
                  if (qName.equalsIgnoreCase("student")) {
                     Iterator<Attribute> attributes = startElement.getAttributes();
                     String rollNo = attributes.next().getValue();
                     if(rollNo.equalsIgnoreCase(requestedRollNo)){
                        System.out.println("Start Element : student");
                        System.out.println("Roll No : " + rollNo);
                        isRequestRollNo = true;
                     }
                  } else if (qName.equalsIgnoreCase("firstname")) {
                     bFirstName = true;
                  } else if (qName.equalsIgnoreCase("lastname")) {
                     bLastName = true;
                  } else if (qName.equalsIgnoreCase("nickname")) {
                     bNickName = true;
                  } else if (qName.equalsIgnoreCase("marks")) {
                     bMarks = true;
                  }				        
                  break;
               case XMLStreamConstants.CHARACTERS:
                  Characters characters = event.asCharacters();
                  if(bFirstName && isRequestRollNo){
                     System.out.println("First Name: " + characters.getData());
                     bFirstName = false;
                  }
                  if(bLastName && isRequestRollNo){
                     System.out.println("Last Name: " + characters.getData());
                     bLastName = false;
                  }
                  if(bNickName && isRequestRollNo){
                     System.out.println("Nick Name: " + characters.getData());
                     bNickName = false;
                  }
                  if(bMarks && isRequestRollNo){
                     System.out.println("Marks: " + characters.getData());
                     bMarks = false;
                  }
                  break;
               case  XMLStreamConstants.END_ELEMENT:
                  EndElement endElement = event.asEndElement();
                  if(endElement.getName().getLocalPart().equalsIgnoreCase("student") && isRequestRollNo){
                     System.out.println("End Element : student");
                     System.out.println();
                     isRequestRollNo = false;
                  }
                  break;
            }		    
         }
      } catch (FileNotFoundException e) {
         e.printStackTrace();
      } catch (XMLStreamException e) {
         e.printStackTrace();
      }
   }
}

โปรแกรมข้างต้นจะสร้างผลลัพธ์ต่อไปนี้ -

Start Element : student
Roll No : 393
First Name: Dinkar
Last Name: Kad
Nick Name: Dinkar
Marks: 85
End Element : student

ตัวอย่างการสาธิต

Here is the XML we need to create −

<?xml version = "1.0" encoding = "UTF-8" standalone = "no"?>
   <cars><supercars company = "Ferrari">
   <carname type = "formula one">Ferrari 101</carname>
   <carname type = "sports">Ferrari 202</carname>
</supercars></cars>

ตัวอย่างการสาธิต

StAXCreateXMLDemo.java

package com.tutorialspoint.xml;

import java.io.IOException;
import java.io.StringWriter;

import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;

public class StAXCreateXMLDemo {
   public static void main(String[] args) {
      try {
         StringWriter stringWriter = new StringWriter();

         XMLOutputFactory xMLOutputFactory = XMLOutputFactory.newInstance();	
         XMLStreamWriter xMLStreamWriter = xMLOutputFactory.createXMLStreamWriter(stringWriter);
   
         xMLStreamWriter.writeStartDocument();
         xMLStreamWriter.writeStartElement("cars");
   
         xMLStreamWriter.writeStartElement("supercars");			
         xMLStreamWriter.writeAttribute("company", "Ferrari");
      
         xMLStreamWriter.writeStartElement("carname");			
         xMLStreamWriter.writeAttribute("type", "formula one");
         xMLStreamWriter.writeCharacters("Ferrari 101");
         xMLStreamWriter.writeEndElement();

         xMLStreamWriter.writeStartElement("carname");			
         xMLStreamWriter.writeAttribute("type", "sports");
         xMLStreamWriter.writeCharacters("Ferrari 202");
         xMLStreamWriter.writeEndElement();

         xMLStreamWriter.writeEndElement();
         xMLStreamWriter.writeEndDocument();

         xMLStreamWriter.flush();
         xMLStreamWriter.close();

         String xmlString = stringWriter.getBuffer().toString();

         stringWriter.close();

         System.out.println(xmlString);

      } catch (XMLStreamException e) {
         e.printStackTrace();
      } catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
      }
   }
}

โปรแกรมข้างต้นจะสร้างผลลัพธ์ต่อไปนี้ -

<?xml version = "1.0" encoding = "UTF-8" standalone = "no"?>
<cars><supercars company = "Ferrari">
<carname type = "formula one">Ferrari 101</carname>
<carname type = "sports">Ferrari 202</carname>
</supercars></cars>

ตัวอย่างการสาธิต

ในการรันตัวอย่างนี้คุณควรมี jdom.jar ใน classpath ของแอปพลิเคชันของคุณ ดาวน์โหลดjdom-2.0.5.zip

นี่คือ XML ที่เราต้องแก้ไข -

<?xml version = "1.0"?>
<class>
   <student rollno = "393">
      <firstname>Dinkar</firstname>
      <lastname>Kad</lastname>
      <nickname>Dinkar</nickname>
      <marks>85</marks>
   </student>
   
   <student rollno = "493">
      <firstname>Vineet</firstname>
      <lastname>Gupta</lastname>
      <nickname>Vinni</nickname>
      <marks>95</marks>
   </student>
   
   <student rollno = "593">
      <firstname>Jasvir</firstname>
      <lastname>Singh</lastname>
      <nickname>Jazz</nickname>
      <marks>90</marks>
   </student>
</class>

ตัวอย่างการสาธิต

StAXModifyDemo.java

package com.tutorialspoint.xml;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;

import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.events.Attribute;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;

import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;

public class StAXModifyDemo {
   public static void main(String[] args) {

      try {
         XMLInputFactory factory = XMLInputFactory.newInstance();
         XMLEventReader eventReader =
            factory.createXMLEventReader(
               new FileReader("input.txt"));
         SAXBuilder saxBuilder = new SAXBuilder();
         Document document = saxBuilder.build(new File("input.txt"));
         Element rootElement = document.getRootElement();
         List<Element> studentElements = rootElement.getChildren("student");
         while(eventReader.hasNext()){
            XMLEvent event = eventReader.nextEvent();
            switch(event.getEventType()){
               case XMLStreamConstants.START_ELEMENT:
               StartElement startElement = event.asStartElement();
               String qName = startElement.getName().getLocalPart();

               if (qName.equalsIgnoreCase("student")) {				        	
                  Iterator<Attribute> attributes = startElement.getAttributes();
                  String rollNo = attributes.next().getValue();				           
                  if(rollNo.equalsIgnoreCase("393")){     	 
                     //get the student with roll no 393				                 
                     for(int i=0;i < studentElements.size();i++){
                        Element studentElement = studentElements.get(i);
                        if(studentElement.getAttribute("rollno").getValue().equalsIgnoreCase("393")){
                           studentElement.removeChild("marks");
                           studentElement.addContent(new Element("marks").setText("80"));
                        }
                    }
                  }
               }       
               break;
            }		    
         }
         XMLOutputter xmlOutput = new XMLOutputter();
         // display xml
         xmlOutput.setFormat(Format.getPrettyFormat());
         xmlOutput.output(document, System.out); 
      } catch (FileNotFoundException e) {
         e.printStackTrace();
      } catch (XMLStreamException e) {
         e.printStackTrace();
      } catch (JDOMException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

โปรแกรมข้างต้นจะสร้างผลลัพธ์ต่อไปนี้ -

<student rollno = "393">
   <firstname>Dinkar</firstname>
   <lastname>Kad</lastname>
   <nickname>Dinkar</nickname>
   <marks>80</marks>
</student>

<student rollno = "493">
   <firstname>Vineet</firstname>
   <lastname>Gupta</lastname>
   <nickname>Vinni</nickname>
   <marks>95</marks>
</student>

<student rollno = "593">
   <firstname>Jasvir</firstname>
   <lastname>Singh</lastname>
   <nickname>Jazz</nickname>
   <marks>90</marks>
</student>