XML 解析是指从 XML 文档中读取数据并将其转换为计算机可处理的格式。在应用程序中,XML 解析通常是将 XML 数据转换为数据结构(如数组、对象或数据库表)的过程,以便应用程序能够使用或存储这些数据。
- XML 解析器是用于解析 XML 文档的程序或库。解析器的任务是读取 XML 文档,识别其中的元素、属性和文本,并将其转换为适当的数据格式。常见的 XML 解析器包括 DOM 解析器、SAX 解析器和 StAX 解析器等。
- DOM 解析器(Document Object Model):将整个 XML 文档加载到内存中,并将其表示为一个树状结构,允许开发人员通过节点访问和操作 XML 文档的任何部分。DOM 解析器适合处理小型 XML 文档,但是对于大型 XML 文档,它会占用大量内存,降低性能。
- SAX 解析器(Simple API for XML):逐行解析 XML 文档,并使用事件驱动方式来响应每个解析事件。SAX 解析器适合处理大型 XML 文档,因为它不需要将整个文档加载到内存中,但是它不支持随机访问节点。
- StAX 解析器(Streaming API for XML):与 SAX 解析器类似,也是逐行解析 XML 文档,但它使用迭代器来访问每个解析事件,并且支持双向遍历,即可以在解析时读取和修改节点。StAX 解析器在处理大小适中的 XML 文件时性能最佳。
解析方式
1、DOM 解析
DOM(Document Object Model)是一种将整个 XML 文档加载到内存中,并将其表示为树状结构的解析方式。在 DOM 模型中,每个节点都是一个对象,开发人员可以通过节点访问和操作 XML 文档的任何部分。
DOM 解析的主要优点是易于使用和直观。开发人员可以很方便地访问和修改 XML 文档中的元素、属性和文本。但这种解析方式有一个重要的缺点,就是对于大型 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;
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();
NodeList nList = doc.getElementsByTagName("student");
for (int i = 0; i < nList.getLength(); i++) {
Node nNode = nList.item(i);
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();
}
}
}
2、SAX 解析
SAX(Simple API for XML)是一种逐行解析 XML 文档,并使用事件驱动方式来响应每个解析事件的解析方式。在 SAX 解析中,XML 文档是顺序解析的,只有当前正在解析的行被加载到内存中,而不是将整个 XML 文档加载到内存中。因此,SAX 解析器适合处理大型 XML 文档。
SAX 解析的主要优点是快速和轻量级。由于只加载一小部分文档到内存中,所以它需要的内存很少。但 SAX 解析的缺点是不支持随机访问节点,因为 XML 文档只是按顺序解析的。此外,它也不容易编写和调试,因为它是通过事件驱动的方式来处理 XML 文本的。
import java.io.File;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
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 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;
}
}
}