Java XML - szybki przewodnik

Co to jest XML?

XML to prosty język tekstowy, który został zaprojektowany do przechowywania i przesyłania danych w formacie zwykłego tekstu. To oznacza Extensible Markup Language. Poniżej przedstawiono niektóre z najważniejszych funkcji języka XML.

  • XML to język znaczników.

  • XML jest językiem opartym na znacznikach, takim jak HTML.

  • Tagi XML nie są predefiniowane, jak HTML.

  • Możesz zdefiniować własne tagi, dlatego nazywa się to językiem rozszerzalnym.

  • Znaczniki XML mają być samoopisowe.

  • XML to zalecenie W3C dotyczące przechowywania i przesyłania danych.

Przykład

<?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>

Zalety

Oto zalety, które zapewnia XML -

  • Technology agnostic- Będąc zwykłym tekstem, XML jest niezależny od technologii. Może być używany przez dowolną technologię do przechowywania i przesyłania danych.

  • Human readable- XML ​​używa prostego formatu tekstowego. Jest czytelny i zrozumiały dla człowieka.

  • Extensible - W języku XML można bardzo łatwo tworzyć i używać niestandardowe tagi.

  • Allow Validation - Korzystanie ze struktur XSD, DTD i XML można łatwo zweryfikować.

Niedogodności

Poniżej przedstawiono wady korzystania z XML -

  • Redundant Syntax - Zwykle pliki XML zawierają wiele powtarzających się terminów.

  • Verbose - Będąc językiem rozwlekłym, rozmiar pliku XML zwiększa koszty transmisji i przechowywania.

Parsowanie XML oznacza przeglądanie dokumentu XML w celu uzyskania dostępu do danych lub ich modyfikacji.

Co to jest parser XML?

Parser XML umożliwia dostęp do danych w dokumencie XML lub modyfikowanie ich. Java udostępnia wiele opcji analizowania dokumentów XML. Poniżej przedstawiono różne typy parserów, które są powszechnie używane do analizowania dokumentów XML.

  • Dom Parser - Analizuje dokument XML, ładując całą zawartość dokumentu i tworząc w pamięci jego pełne drzewo hierarchiczne.

  • SAX Parser- Analizuje dokument XML pod kątem wyzwalaczy opartych na zdarzeniach. Nie ładuje całego dokumentu do pamięci.

  • JDOM Parser - Analizuje dokument XML w podobny sposób jak parser DOM, ale w łatwiejszy sposób.

  • StAX Parser - Analizuje dokument XML w podobny sposób jak parser SAX, ale w bardziej wydajny sposób.

  • XPath Parser - Analizuje dokument XML na podstawie wyrażenia i jest często używany w połączeniu z XSLT.

  • DOM4J Parser- Biblioteka java do analizowania XML, XPath i XSLT przy użyciu Java Collections Framework. Zapewnia obsługę DOM, SAX i JAXP.

Dostępne są interfejsy API JAXB i XSLT do obsługi analizowania XML w sposób obiektowy. Szczegółowo omówimy każdy parser w kolejnych rozdziałach tego samouczka.

Document Object Model (DOM) to oficjalna rekomendacja World Wide Web Consortium (W3C). Definiuje interfejs, który umożliwia programom dostęp i aktualizację stylu, struktury i zawartości dokumentów XML. Parsery XML obsługujące DOM implementują ten interfejs.

Kiedy użyć?

Powinieneś używać parsera DOM, gdy -

  • Musisz dużo wiedzieć o strukturze dokumentu.

  • Musisz przenieść części dokumentu XML (możesz na przykład posortować pewne elementy).

  • Musisz użyć informacji zawartych w dokumencie XML więcej niż raz.

Co dostałeś?

Kiedy parsujesz dokument XML za pomocą parsera DOM, otrzymujesz strukturę drzewa, która zawiera wszystkie elementy twojego dokumentu. DOM zapewnia różnorodne funkcje, których możesz użyć do zbadania zawartości i struktury dokumentu.

Zalety

DOM jest wspólnym interfejsem do manipulowania strukturami dokumentów. Jednym z jego celów projektowych jest to, że kod Java napisany dla jednego parsera zgodnego z DOM powinien działać na każdym innym parserze zgodnym z DOM bez konieczności dokonywania jakichkolwiek modyfikacji.

Interfejsy DOM

DOM definiuje kilka interfejsów Java. Oto najpopularniejsze interfejsy -

  • Node - Podstawowy typ danych DOM.

  • Element - Zdecydowana większość obiektów, z którymi będziesz mieć do czynienia, to elementy.

  • Attr - Reprezentuje atrybut elementu.

  • Text - rzeczywista zawartość elementu lub atrybutu.

  • Document- Reprezentuje cały dokument XML. Obiekt Document jest często nazywany drzewem DOM.

Popularne metody DOM

Podczas pracy z DOM jest kilka metod, których będziesz często używać -

  • Document.getDocumentElement() - Zwraca element główny dokumentu.

  • Node.getFirstChild() - Zwraca pierwsze dziecko danego węzła.

  • Node.getLastChild() - zwraca ostatnie dziecko danego węzła.

  • Node.getNextSibling() - Te metody zwracają następny element równorzędny danego węzła.

  • Node.getPreviousSibling() - Te metody zwracają poprzedni element równorzędny danego węzła.

  • Node.getAttribute(attrName) - Dla danego węzła zwraca atrybut o żądanej nazwie.

Kroki do korzystania z JDOM

Poniżej przedstawiono kroki stosowane podczas analizowania dokumentu za pomocą JDOM Parser.

  • Importuj pakiety związane z XML.
  • Utwórz DocumentBuilder
  • Utwórz dokument z pliku lub strumienia
  • Wyodrębnij element główny
  • Zbadaj atrybuty
  • Zbadaj elementy podrzędne

Importuj pakiety związane z XML

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

Utwórz DocumentBuilder

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

Utwórz dokument z pliku lub strumienia

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

Wyodrębnij element główny

Element root = document.getDocumentElement();

Zbadaj atrybuty

//returns specific attribute
getAttribute("attributeName");

//returns a Map (table) of names/values
getAttributes();

Zbadaj elementy podrzędne

//returns a list of subelements of specified name
getElementsByTagName("subelementName");

//returns a list of all child nodes
getChildNodes();

Przykład demo

Oto wejściowy plik xml, który musimy przeanalizować -

<?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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>
   
   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</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();
      }
   }
}

Dałoby to następujący wynik -

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 : Vaneet
Last Name : Gupta
Nick Name : vinni
Marks : 95

Current Element :student
Student roll no : 593
First Name : jasvir
Last Name : singn
Nick Name : jazz
Marks : 90

Przykład demo

Oto wejściowy plik xml, który musimy zapytać -

<?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();
      }
   }
}

Dałoby to następujący wynik -

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

Current Element :
supercarscompany : 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 :
supercarscompany : Lamborgini
car name : Lamborgini 001
car type : 
car name : Lamborgini 002
car type : 
car name : Lamborgini 003
car type :

Przykład demo

Oto plik XML, który musimy utworzyć -

<?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();
      }
   }
}

Dałoby to następujący wynik -

<?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>

Przykład demo

Oto wejściowy plik xml, który musimy zmodyfikować -

<?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.xml");
         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();
      }
   }
}

Dałoby to następujący wynik -

-----------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 for XML) to oparty na zdarzeniach parser dokumentów XML. W przeciwieństwie do parsera DOM, parser SAX nie tworzy drzewa parsowania. SAX jest interfejsem strumieniowym dla XML, co oznacza, że ​​aplikacje korzystające z SAX otrzymują powiadomienia o zdarzeniach dotyczących przetwarzanego dokumentu XML, elementu i atrybutu, w czasie w kolejności sekwencyjnej, począwszy od góry dokumentu, a kończąc na zamknięciu elementu Element ROOT.

  • Odczytuje dokument XML od góry do dołu, rozpoznając tokeny, które składają się na dobrze sformułowany dokument XML.

  • Tokeny są przetwarzane w tej samej kolejności, w jakiej pojawiają się w dokumencie.

  • Informuje aplikację o naturze tokenów napotkanych przez analizator składni w momencie ich wystąpienia.

  • Aplikacja zapewnia obsługę „zdarzenia”, którą należy zarejestrować w parserze.

  • Gdy tokeny są identyfikowane, wywoływane są metody wywołania zwrotnego w module obsługi z odpowiednimi informacjami.

Kiedy użyć?

Powinieneś użyć parsera SAX, gdy -

  • Możesz przetwarzać dokument XML w sposób liniowy od góry do dołu.

  • Dokument nie jest głęboko zagnieżdżony.

  • Przetwarzasz bardzo duży dokument XML, którego drzewo DOM zużywałoby zbyt dużo pamięci. Typowe implementacje DOM używają dziesięciu bajtów pamięci do reprezentowania jednego bajtu XML.

  • Problem do rozwiązania dotyczy tylko części dokumentu XML.

  • Dane są dostępne, gdy tylko zostaną odczytane przez parser, więc SAX działa dobrze w przypadku dokumentu XML, który dociera do strumienia.

Wady SAX

  • Nie mamy losowego dostępu do dokumentu XML, ponieważ jest on przetwarzany tylko do przodu.

  • Jeśli chcesz śledzić dane, które parser widział lub zmienić kolejność elementów, musisz samodzielnie napisać kod i przechowywać dane.

Interfejs ContentHandler

Ten interfejs określa metody wywołania zwrotnego, których parser SAX używa do powiadamiania aplikacji o składnikach dokumentu XML, które widział.

  • void startDocument() - Wywołane na początku dokumentu.

  • void endDocument() - Wywołane na końcu dokumentu.

  • void startElement(String uri, String localName, String qName, Attributes atts) - Wywoływane na początku elementu.

  • void endElement(String uri, String localName,String qName) - Wywoływane na końcu elementu.

  • void characters(char[] ch, int start, int length) - Wywoływane w przypadku napotkania danych postaci.

  • void ignorableWhitespace( char[] ch, int start, int length) - Wywoływane, gdy obecne jest DTD i napotkano możliwe do zignorowania białe znaki.

  • void processingInstruction(String target, String data) - Wywoływane po rozpoznaniu instrukcji przetwarzania.

  • void setDocumentLocator(Locator locator)) - Zapewnia lokalizator, którego można użyć do identyfikacji pozycji w dokumencie.

  • void skippedEntity(String name) - Wywoływane, gdy zostanie napotkany nierozwiązany podmiot.

  • void startPrefixMapping(String prefix, String uri) - Wywoływane, gdy zdefiniowano nowe odwzorowanie przestrzeni nazw.

  • void endPrefixMapping(String prefix) - Wywoływane, gdy definicja przestrzeni nazw kończy swój zakres.

Interfejs atrybutów

Ten interfejs określa metody przetwarzania atrybutów połączonych z elementem.

  • int getLength() - Zwraca liczbę atrybutów.

  • String getQName(int index)

  • String getValue(int index)

  • String getValue(String qname)

Przykład demo

Oto wejściowy plik xml, który musimy przeanalizować -

<?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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>
   
   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</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;
      }
   }
}

Dałoby to następujący wynik -

Roll No : 393
First Name: dinkar
Last Name: kad
Nick Name: dinkar
Marks: 85
End Element :student
Roll No : 493
First Name: Vaneet
Last Name: Gupta
Nick Name: vinni
Marks: 95
End Element :student
Roll No : 593
First Name: jasvir
Last Name: singn
Nick Name: jazz
Marks: 90
End Element :student

Przykład demo

Oto wejściowy plik tekstowy, którego potrzebujemy do zapytania o rollno: 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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>
   
   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</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;
      }
   }
}

Dałoby to następujący wynik -

Start Element :student
First Name: dinkar
Last Name: kad
Nick Name: dinkar
Marks: 85
End Element :student

It is better to use StAX parser for creating XML documents rather than using SAX parser. Please refer the Java StAX Parser section for the same.

Przykład demo

Oto wejściowy plik XML, który musimy zmodyfikować, dołączając <Result> Pass <Result /> na końcu tagu </marks>.

<?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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>
   
   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</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");
      }
   }
}

Dałoby to następujący wynik -

<?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>
         Vaneet
      </firstname>
      <lastname>
         Gupta
      </lastname>
      <nickname>
         vinni
      </nickname>
      <marks>
         95
      </marks>
      <Result>
         Pass
      </Result>
   </student>
   <student rollno = "593">
      <firstname>
         jasvir
      </firstname>
      <lastname>
         singn
      </lastname>
      <nickname>
         jazz
      </nickname>
      <marks>
         90
      </marks>
      <Result>
         Pass
      </Result>
   </student>
</class>

JDOM to oparta na Javie biblioteka open source do analizowania dokumentów XML. Zwykle jest to interfejs API przyjazny dla programistów Java. Jest zoptymalizowany pod kątem języka Java i korzysta z kolekcji Java, takich jak lista i tablice.

JDOM współpracuje z API DOM i SAX i łączy to, co najlepsze z tych dwóch. Zajmuje mało pamięci i jest prawie tak szybki jak SAX.

Konfiguracja środowiska

Aby korzystać z parsera JDOM, w ścieżce klas aplikacji należy umieścić jdom.jar. Pobierz jdom-2.0.5.zip.

Kiedy użyć?

Powinieneś użyć parsera JDOM, gdy -

  • Musisz dużo wiedzieć o strukturze dokumentu XML.

  • Musisz przenosić części dokumentu XMl (na przykład możesz chcieć posortować pewne elementy).

  • Musisz użyć informacji zawartych w dokumencie XML więcej niż raz.

  • Jesteś programistą Java i chcesz wykorzystać analizę XML zoptymalizowaną pod kątem języka Java.

Co dostałeś?

Analizując dokument XML za pomocą parsera JDOM, uzyskuje się elastyczność w odzyskaniu struktury drzewa, która zawiera wszystkie elementy dokumentu, bez wpływu na wielkość pamięci aplikacji.

JDOM zapewnia różnorodne funkcje narzędziowe, których można użyć do zbadania zawartości i struktury dokumentu XML w przypadku, gdy dokument jest dobrze zorganizowany, a jego struktura jest znana.

Zalety

JDOM zapewnia programistom Java elastyczność i łatwość utrzymania kodu analizującego XML. Jest to lekki i szybki interfejs API.

Klasy JDOM

JDOM definiuje kilka klas Java. Oto najpopularniejsze zajęcia -

  • Document- Reprezentuje cały dokument XML. Obiekt Document jest często nazywany drzewem DOM.

  • Element- Reprezentuje element XML. Obiekt Element ma metody do manipulowania jego elementami podrzędnymi, tekstem, atrybutami i przestrzeniami nazw.

  • Attribute- Reprezentuje atrybut elementu. Atrybut ma metodę pobierania i ustawiania wartości atrybutu. Ma rodzica i typ atrybutu.

  • Text - Reprezentuje tekst znacznika XML.

  • Comment - Reprezentuje komentarze w dokumencie XML.

Popularne metody JDOM

Podczas pracy z JDOM istnieje kilka metod, których będziesz często używać -

  • SAXBuilder.build(xmlSource)() - Zbuduj dokument JDOM ze źródła xml.

  • Document.getRootElement() - Pobierz element główny XML.

  • Element.getName() - Uzyskaj nazwę węzła XML.

  • Element.getChildren() - Pobierz wszystkie bezpośrednie węzły potomne elementu.

  • Node.getChildren(Name) - Pobierz wszystkie bezpośrednie węzły potomne o podanej nazwie.

  • Node.getChild(Name) - Pobierz pierwszy węzeł podrzędny o podanej nazwie.

Kroki do korzystania z JDOM

Poniżej przedstawiono kroki stosowane podczas analizowania dokumentu za pomocą JDOM Parser.

  • Importuj pakiety związane z XML.
  • Utwórz SAXBuilder
  • Utwórz dokument z pliku lub strumienia
  • Wyodrębnij element główny
  • Zbadaj atrybuty
  • Zbadaj elementy podrzędne

Importuj pakiety związane z XML

import java.io.*;
import java.util.*;
import org.jdom2.*;

Utwórz DocumentBuilder

SAXBuilder saxBuilder = new SAXBuilder();

Utwórz dokument z pliku lub strumienia

File inputFile = new File("input.txt");
SAXBuilder saxBuilder = new SAXBuilder();
Document document = saxBuilder.build(inputFile);

Wyodrębnij element główny

Element classElement = document.getRootElement();

Zbadaj atrybuty

//returns specific attribute
getAttribute("attributeName");

Zbadaj elementy podrzędne

//returns a list of subelements of specified name
getChildren("subelementName"); 

//returns a list of all child nodes
getChildren(); 

//returns first child node
getChild("subelementName");

Przykład demo

Oto wejściowy plik xml, który musimy przeanalizować -

<?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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>
   
   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</lastname>
      <nickname>jazz</nickname>
      <marks>90</marks>
   </student>
</class>

DomParserDemo.java

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;


public class JDomParserDemo {

   public static void main(String[] args) {

      try {
         File inputFile = new File("input.txt");
         SAXBuilder saxBuilder = new SAXBuilder();
         Document document = saxBuilder.build(inputFile);
         System.out.println("Root element :" + document.getRootElement().getName());
         Element classElement = document.getRootElement();

         List<Element> studentList = classElement.getChildren();
         System.out.println("----------------------------");

         for (int temp = 0; temp < studentList.size(); temp++) {    
            Element student = studentList.get(temp);
            System.out.println("\nCurrent Element :" 
               + student.getName());
            Attribute attribute =  student.getAttribute("rollno");
            System.out.println("Student roll no : " 
               + attribute.getValue() );
            System.out.println("First Name : "
               + student.getChild("firstname").getText());
            System.out.println("Last Name : "
               + student.getChild("lastname").getText());
            System.out.println("Nick Name : "
               + student.getChild("nickname").getText());
            System.out.println("Marks : "
               + student.getChild("marks").getText());
         }
      } catch(JDOMException e) {
         e.printStackTrace();
      } catch(IOException ioe) {
         ioe.printStackTrace();
      }
   }
}

Dałoby to następujący wynik -

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 : Vaneet
Last Name : Gupta
Nick Name : vinni
Marks : 95

Current Element :student
Student roll no : 593
First Name : jasvir
Last Name : singn
Nick Name : jazz
Marks : 90

Przykład demo

Oto wejściowy plik xml, który musimy zapytać -

<?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

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;


public class QueryXmlFileDemo {

   public static void main(String[] args) {

      try {
         File inputFile = new File("input.txt");
         SAXBuilder saxBuilder = new SAXBuilder();
         Document document = saxBuilder.build(inputFile);
         System.out.println("Root element :" + document.getRootElement().getName());
         Element classElement = document.getRootElement();

         List<Element> supercarList = classElement.getChildren("supercars");
         System.out.println("----------------------------");

         for (int temp = 0; temp < supercarList.size(); temp++) {    
            Element supercarElement = supercarList.get(temp);
            System.out.println("\nCurrent Element :" + supercarElement.getName());
            Attribute attribute = supercarElement.getAttribute("company");
            System.out.println("company : " + attribute.getValue() );
            List<Element> carNameList = supercarElement.getChildren("carname");
            
            for (int count = 0; count < carNameList.size(); count++) {	 
               Element carElement = carNameList.get(count);
               System.out.print("car name : ");
               System.out.println(carElement.getText());
               System.out.print("car type : ");
               Attribute typeAttribute = carElement.getAttribute("type");
               
               if(typeAttribute != null)
                  System.out.println(typeAttribute.getValue());
               else {
                  System.out.println("");
               }
            }
         }
      } catch(JDOMException e) {
         e.printStackTrace();
      } catch(IOException ioe) {
         ioe.printStackTrace();
      }
   }
}

Dałoby to następujący wynik -

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 :

Przykład demo

Oto plik XML, który musimy utworzyć -

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

CreateXmlFileDemo.java

import java.io.IOException;

import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.output.Format;
import org.jdom2.output.XMLOutputter;


public class CreateXmlFileDemo {

   public static void main(String[] args) {

      try{
         //root element
         Element carsElement = new Element("cars");
         Document doc = new Document(carsElement);

         //supercars element
         Element supercarElement = new Element("supercars");
         supercarElement.setAttribute(new Attribute("company","Ferrari"));

         //supercars element
         Element carElement1 = new Element("carname");
         carElement1.setAttribute(new Attribute("type","formula one"));
         carElement1.setText("Ferrari 101");

         Element carElement2 = new Element("carname");
         carElement2.setAttribute(new Attribute("type","sports"));
         carElement2.setText("Ferrari 202");

         supercarElement.addContent(carElement1);
         supercarElement.addContent(carElement2);

         doc.getRootElement().addContent(supercarElement);

         XMLOutputter xmlOutput = new XMLOutputter();

         // display ml
         xmlOutput.setFormat(Format.getPrettyFormat());
         xmlOutput.output(doc, System.out); 
      } catch(IOException e) {
         e.printStackTrace();
      }
   }
}

Dałoby to następujący wynik -

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

Przykład demo

Oto wejściowy plik tekstowy, który musimy zmodyfikować -

<?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

import java.io.File;
import java.io.IOException;
import java.util.List;

import org.jdom2.Attribute;
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 ModifyXMLFileDemo {

   public static void main(String[] args) {

      try {
         File inputFile = new File("input.txt");
         SAXBuilder saxBuilder = new SAXBuilder();
         Document document = saxBuilder.build(inputFile);
         Element rootElement = document.getRootElement();

         //get first supercar
         Element supercarElement = rootElement.getChild("supercars");

         // update supercar attribute
         Attribute attribute = supercarElement.getAttribute("company");
         attribute.setValue("Lamborigini");

         // loop the supercar child node
         List<Element> list = supercarElement.getChildren();
         
         for (int temp = 0; temp < list.size(); temp++) {
            Element carElement = list.get(temp);
            
            if("Ferrari 101".equals(carElement.getText())) {
               carElement.setText("Lamborigini 001");
            }
            if("Ferrari 202".equals(carElement.getText())) {
               carElement.setText("Lamborigini 002");
            }
         }

         //get all supercars element
         List<Element> supercarslist = rootElement.getChildren();
         
         for (int temp = 0; temp < supercarslist.size(); temp++) {
            Element tempElement = supercarslist.get(temp);
            
            if("luxurycars".equals(tempElement.getName())) {
               rootElement.removeContent(tempElement);
            }        	 
         }

         XMLOutputter xmlOutput = new XMLOutputter();
   
         // display xml
         xmlOutput.setFormat(Format.getPrettyFormat());
         xmlOutput.output(document, System.out); 
      } catch (JDOMException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

Dałoby to następujący wynik -

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

StAX to oparty na Javie interfejs API do analizowania dokumentów XML w podobny sposób jak parser SAX. Są jednak dwie główne różnice między tymi dwoma interfejsami API -

  • StAX to PULL API, natomiast SAX to PUSH API. Oznacza to, że w przypadku parsera StAX aplikacja kliencka musi poprosić parser StAX o pobranie informacji z XML, kiedy tylko tego potrzebuje. Jednak w przypadku parsera SAX aplikacja kliencka jest wymagana do uzyskania informacji, gdy parser SAX powiadamia aplikację kliencką, że informacje są dostępne.

  • StAX API może czytać i zapisywać dokumenty XML. Za pomocą SAX API można tylko czytać plik XML.

Konfiguracja środowiska

Aby użyć parsera StAX, powinieneś mieć stax.jar w ścieżce klas aplikacji.

Oto cechy StAX API -

  • Odczytuje dokument XML od góry do dołu, rozpoznając tokeny, które składają się na dobrze sformułowany dokument XML.

  • Tokeny są przetwarzane w tej samej kolejności, w jakiej pojawiają się w dokumencie.

  • Informuje aplikację o naturze tokenów napotkanych przez analizator składni w momencie ich wystąpienia.

  • Aplikacja zapewnia czytnik „zdarzeń”, który działa jako iterator i wykonuje iterację po zdarzeniu, aby uzyskać wymagane informacje. Innym dostępnym czytnikiem jest „kursor”, który działa jako wskaźnik do węzłów XML.

  • Po zidentyfikowaniu zdarzeń elementy XML można pobierać z obiektu zdarzenia i dalej przetwarzać.

Kiedy użyć?

Powinieneś użyć parsera StAX, gdy -

  • Możesz przetwarzać dokument XML w sposób liniowy od góry do dołu.

  • Dokument nie jest głęboko zagnieżdżony.

  • Przetwarzasz bardzo duży dokument XML, którego drzewo DOM zużywałoby zbyt dużo pamięci. Typowe implementacje DOM używają dziesięciu bajtów pamięci do reprezentowania jednego bajtu XML.

  • Problem do rozwiązania dotyczy tylko części dokumentu XML.

  • Dane są dostępne, gdy tylko zostaną odczytane przez parser, więc StAX działa dobrze dla dokumentu XML, który dociera do strumienia.

Wady SAX

  • Nie mamy losowego dostępu do dokumentu XML, ponieważ jest on przetwarzany tylko do przodu.

  • Jeśli chcesz śledzić dane, które parser widział lub gdzie parser zmienił kolejność elementów, musisz sam napisać kod i przechowywać dane.

Klasa XMLEventReader

Ta klasa zapewnia iterator zdarzeń, które mogą być używane do iteracji po zdarzeniach, które występują podczas analizowania dokumentu XML.

  • StartElement asStartElement() - Służy do pobierania wartości i atrybutów elementu.

  • EndElement asEndElement() - Wywoływane na końcu elementu.

  • Characters asCharacters() - Może służyć do uzyskiwania znaków, takich jak CDATA, białe znaki itp.

Klasa XMLEventWriter

Ten interfejs określa metody tworzenia zdarzenia.

  • add(Event event) - Dodaj wydarzenie zawierające elementy do XML.

Klasa XMLStreamReader

Ta klasa zapewnia iterator zdarzeń, które mogą być używane do iteracji po zdarzeniach, które występują podczas analizowania dokumentu XML.

  • int next() - Służy do pobierania następnego zdarzenia.

  • boolean hasNext() - Służy do sprawdzania, czy istnieją dalsze wydarzenia, czy nie.

  • String getText() - Służy do pobierania tekstu elementu.

  • String getLocalName() - Używany do uzyskania nazwy elementu.

Klasa XMLStreamWriter

Ten interfejs określa metody tworzenia zdarzenia.

  • writeStartElement(String localName) - Dodaj element początkowy o podanej nazwie.

  • writeEndElement(String localName) - Dodaj element końcowy o podanej nazwie.

  • writeAttribute(String localName, String value) - Zapisz atrybuty do elementu.

Przykład demo

Oto wejściowy plik xml, który musimy przeanalizować -

<?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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>
   
   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</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();
      }
   }
}

Dałoby to następujący wynik -

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: Vaneet
Last Name: Gupta
Nick Name: vinni
Marks: 95
End Element : student

Start Element : student
Roll No : 593
First Name: jasvir
Last Name: singn
Nick Name: jazz
Marks: 90
End Element : student

Przykład demo

Oto wejściowy plik xml, który musimy przeanalizować -

<?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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>
   
   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</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();
      }
   }
}

Dałoby to następujący wynik -

Start Element : student
Roll No : 393
First Name: dinkar
Last Name: kad
Nick Name: dinkar
Marks: 85
End Element : student

Przykład demo

Oto plik XML, który musimy utworzyć -

<?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();
      }
   }
}

Dałoby to następujący wynik -

<?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>

Przykład demo

Oto plik XML, który musimy zmodyfikować -

<?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>Vaneet</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();
      }
   }
}

Dałoby to następujący wynik -

<?xml version = "1.0" encoding = "UTF-8"?>
<student rollno = "393">
   <firstname>dinkar</firstname>
   <lastname>kad</lastname>
   <nickname>dinkar</nickname>
   <marks>80</marks>
</student>
<student rollno = "493">
   <firstname>Vaneet</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>

XPath jest oficjalną rekomendacją World Wide Web Consortium (W3C). Definiuje język, w którym można znaleźć informacje w pliku XML. Służy do przechodzenia między elementami i atrybutami dokumentu XML. XPath udostępnia różne typy wyrażeń, których można używać do uzyskiwania odpowiednich informacji z dokumentu XML.

Co to jest XPath?

  • Structure Definations - XPath definiuje części dokumentu XML, takie jak element, atrybut, tekst, przestrzeń nazw, instrukcja przetwarzania, komentarz i węzły dokumentu.

  • Path Expressions - XPath zapewnia potężne wyrażenia ścieżek, takie jak wybrane węzły lub lista węzłów w dokumentach XML.

  • Standard Functions - XPath zapewnia bogatą bibliotekę standardowych funkcji do manipulacji wartościami łańcuchowymi, wartościami liczbowymi, porównywaniem dat i godzin, manipulowaniem węzłami i nazwami QName, manipulowaniem sekwencjami, wartościami logicznymi itp.

  • Major part of XSLT - XPath jest jednym z głównych elementów standardu XSLT i aby pracować z dokumentami XSLT, trzeba mieć wystarczającą znajomość XPath.

  • W3C recommendation - XPath jest oficjalną rekomendacją World Wide Web Consortium (W3C).

Wyrażenia XPath

XPath używa wyrażenia ścieżki, aby wybrać węzeł lub listę węzłów z dokumentu XML. Poniżej znajduje się lista przydatnych ścieżek i wyrażeń umożliwiających wybranie dowolnego węzła / listy węzłów z dokumentu XML.

Sr.No. Wyrażenie i opis
1

node-name

Wybierz wszystkie węzły o podanej nazwie „nazwa węzła”

2

/

Wybór rozpoczyna się od węzła głównego

3

//

Wybór rozpoczyna się od bieżącego węzła, który pasuje do wyboru

4

.

Wybiera bieżący węzeł

5

..

Wybiera rodzica bieżącego węzła

6

@

Wybiera atrybuty

7

student

Example - Wybiera wszystkie węzły o nazwie „student”

8

class/student

Example - Wybiera wszystkie elementy uczniów, które są dziećmi klasy

9

//student

Zaznacza wszystkie elementy uczniów bez względu na to, gdzie się znajdują w dokumencie

Predykaty

Predykaty służą do znajdowania określonego węzła lub węzła zawierającego określoną wartość i są definiowane za pomocą [...].

Wyrażenie Wynik
/ klasa / uczeń [1] Wybiera pierwszy element ucznia będący dzieckiem elementu klasy.
/ klasa / uczeń [ostatni ()] Wybiera ostatni element ucznia będący dzieckiem elementu class.
/ klasa / uczeń [ostatni () - 1] Wybiera przedostatni element ucznia, który jest dzieckiem elementu class.
// student [@rollno = '493'] Wybiera wszystkie elementy uczniów, które mają atrybut o nazwie rollno o wartości „493”

Kroki do korzystania z XPath

Poniżej przedstawiono kroki używane podczas analizowania dokumentu przy użyciu parsera XPath.

  • Importuj pakiety związane z XML.

  • Utwórz DocumentBuilder.

  • Utwórz dokument z pliku lub strumienia.

  • Utwórz obiekt Xpath i wyrażenie ścieżki XPath.

  • Skompiluj wyrażenie XPath przy użyciu XPath.compile() i uzyskaj listę węzłów, oceniając skompilowane wyrażenie za pomocą XPath.evaluate().

  • Powtarzaj listę węzłów.

  • Zbadaj atrybuty.

  • Zbadaj elementy podrzędne.

Importuj pakiety związane z XML

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

Utwórz DocumentBuilder

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

Utwórz dokument z pliku lub strumienia

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);

Zbuduj XPath

XPath xPath =  XPathFactory.newInstance().newXPath();

Przygotuj wyrażenie Path i oceń je

String expression = "/class/student";	        
NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(
   doc, XPathConstants.NODESET);

Wykonaj iterację po NodeList

for (int i = 0; i < nodeList.getLength(); i++) {
   Node nNode = nodeList.item(i);
   ...
}

Zbadaj atrybuty

//returns specific attribute
getAttribute("attributeName");

//returns a Map (table) of names/values
getAttributes();

Zbadaj elementy podrzędne

//returns a list of subelements of specified name
getElementsByTagName("subelementName");

//returns a list of all child nodes
getChildNodes();

Przykład demo

Oto wejściowy plik tekstowy, który musimy przeanalizować -

<?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>Vaneet</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>

XPathParserDemo.java

package com.tutorialspoint.xml;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

public class XPathParserDemo {
   
   public static void main(String[] args) {
      
      try {
         File inputFile = new File("input.txt");
         DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
         DocumentBuilder dBuilder;

         dBuilder = dbFactory.newDocumentBuilder();

         Document doc = dBuilder.parse(inputFile);
         doc.getDocumentElement().normalize();

         XPath xPath =  XPathFactory.newInstance().newXPath();

         String expression = "/class/student";	        
         NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(
            doc, XPathConstants.NODESET);

         for (int i = 0; i < nodeList.getLength(); i++) {
            Node nNode = nodeList.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 (ParserConfigurationException e) {
         e.printStackTrace();
      } catch (SAXException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      } catch (XPathExpressionException e) {
         e.printStackTrace();
      }
   }
}

Dałoby to następujący wynik -

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 : Vaneet
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

Przykład demo

Oto wejściowy plik tekstowy, który musimy zapytać -

<?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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>
   
   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</lastname>
      <nickname>jazz</nickname>
      <marks>90</marks>
   </student>
</class>

XPathParserDemo.java

package com.tutorialspoint.xml;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

public class XPathParserDemo {

   public static void main(String[] args) {
      
      try {
         File inputFile = new File("input.txt");
         DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
         DocumentBuilder dBuilder;

         dBuilder = dbFactory.newDocumentBuilder();

         Document doc = dBuilder.parse(inputFile);
         doc.getDocumentElement().normalize();

         XPath xPath =  XPathFactory.newInstance().newXPath();

         String expression = "/class/student[@rollno = '493']";
         NodeList nodeList = (NodeList) xPath.compile(expression).evaluate(
            doc, XPathConstants.NODESET);
         
         for (int i = 0; i < nodeList.getLength(); i++) {
            Node nNode = nodeList.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 (ParserConfigurationException e) {
         e.printStackTrace();
      } catch (SAXException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      } catch (XPathExpressionException e) {
         e.printStackTrace();
      }
   }
}

Dałoby to następujący wynik -

Current Element :student
Student roll no : 493
First Name : Vaneet
Last Name : Gupta
Nick Name : vinni
Marks : 95

XPath parser is used to navigate XML Documents only. It is better to use DOM parser for creating XML. Please refer the Java DOM Parser section for the same.

XPath parser is used to navigate XML Documents only. It is better to use DOM parser for modifying XML. Please refer the Java DOM Parser section for the same.

DOM4J to oparta na Javie biblioteka open source do analizowania dokumentów XML. Jest to wysoce elastyczny i wydajny interfejs API. Jest zoptymalizowany pod kątem języka Java i wykorzystuje kolekcje Java, takie jak lista i tablice.

DOM4J współpracuje z DOM, SAX, XPath i XSLT. Potrafi analizować duże dokumenty XML o bardzo małej ilości pamięci.

Konfiguracja środowiska

Aby korzystać z parsera DOM4J, w ścieżce klas aplikacji należy umieścić domeny dom4j-1.6.1.jar i jaxen.jar. Pobierz dom4j-1.6.1.zip.

Kiedy użyć?

Powinieneś użyć parsera DOM4J, gdy -

  • Musisz dużo wiedzieć o strukturze dokumentu XML.

  • Musisz przenieść części dokumentu XML (możesz na przykład posortować pewne elementy).

  • Musisz użyć informacji zawartych w dokumencie XML więcej niż raz.

  • Jesteś programistą Java i chcesz korzystać z analizowania XML zoptymalizowanego pod kątem języka Java.

Co dostałeś?

Kiedy parsujesz dokument XML za pomocą parsera DOM4J, możesz odzyskać strukturę drzewa zawierającą wszystkie elementy twojego dokumentu bez wpływu na pamięć aplikacji.

DOM4J zapewnia różnorodne funkcje narzędziowe, których możesz użyć do zbadania zawartości i struktury dokumentu XML w przypadku, gdy dokument jest dobrze zorganizowany, a jego struktura jest znana.

DOM4J używa wyrażenia XPath do nawigacji w dokumencie XML.

Zalety

DOM4J zapewnia programistom Java elastyczność i łatwość obsługi kodu parsującego XML. Jest to lekki i szybki interfejs API.

Klasy DOM4J

DOM4J definiuje kilka klas Java. Oto najpopularniejsze zajęcia -

  • Document- Reprezentuje cały dokument XML. Obiekt Document jest często nazywany drzewem DOM.

  • Element- Reprezentuje element XML. Obiekt Element ma metody do manipulowania jego elementami podrzędnymi, tekstem, atrybutami i przestrzeniami nazw.

  • Attribute- Reprezentuje atrybut elementu. Atrybut ma metodę pobierania i ustawiania wartości atrybutu. Ma rodzica i typ atrybutu.

  • Node - Reprezentuje element, atrybut lub instrukcję przetwarzania.

Popularne metody DOM4J

Podczas pracy z DOM4J istnieje kilka metod, których będziesz często używać -

  • SAXReader.read(xmlSource)() - Zbuduj dokument DOM4J ze źródła XML.

  • Document.getRootElement() - Pobierz element główny dokumentu XML.

  • Element.node(index) - Pobierz węzeł XML w określonym indeksie w elemencie.

  • Element.attributes() - Uzyskaj wszystkie atrybuty elementu.

  • Node.valueOf(@Name) - Pobierz wartości atrybutu o podanej nazwie elementu.

Kroki do korzystania z DOM4J

Poniżej przedstawiono kroki używane podczas analizowania dokumentu przy użyciu Parsera DOM4J.

  • Importuj pakiety związane z XML.

  • Utwórz SAXReader.

  • Utwórz dokument z pliku lub strumienia.

  • Pobierz wymagane węzły za pomocą wyrażenia XPath, wywołując document.selectNodes ()

  • Wyodrębnij element główny.

  • Powtarzaj listę węzłów.

  • Zbadaj atrybuty.

  • Zbadaj elementy podrzędne.

Importuj pakiety związane z XML

import java.io.*;
import java.util.*;
import org.dom4j.*;

Utwórz DocumentBuilder

SAXBuilder saxBuilder = new SAXBuilder();

Utwórz dokument z pliku lub strumienia

File inputFile = new File("input.txt");
SAXBuilder saxBuilder = new SAXBuilder();
Document document = saxBuilder.build(inputFile);

Wyodrębnij element główny

Element classElement = document.getRootElement();

Zbadaj atrybuty

//returns specific attribute
valueOf("@attributeName");

Zbadaj elementy podrzędne

//returns first child node
selectSingleNode("subelementName");

Przykład demo

Oto wejściowy plik xml, który musimy przeanalizować -

<?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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>
   
   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</lastname>
      <nickname>jazz</nickname>
      <marks>90</marks>
   </student>
</class>

DOM4JParserDemo.java

package com.tutorialspoint.xml;

import java.io.File;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

public class DOM4JParserDemo {

   public static void main(String[] args) {

      try {
         File inputFile = new File("input.txt");
         SAXReader reader = new SAXReader();
         Document document = reader.read( inputFile );

         System.out.println("Root element :" + document.getRootElement().getName());

         Element classElement = document.getRootElement();

         List<Node> nodes = document.selectNodes("/class/student" );
         System.out.println("----------------------------");
         
         for (Node node : nodes) {
            System.out.println("\nCurrent Element :"
               + node.getName());
            System.out.println("Student roll no : " 
               + node.valueOf("@rollno") );
            System.out.println("First Name : "
               + node.selectSingleNode("firstname").getText());
            System.out.println("Last Name : "
               + node.selectSingleNode("lastname").getText());
            System.out.println("First Name : "
               + node.selectSingleNode("nickname").getText());
            System.out.println("Marks : "
               + node.selectSingleNode("marks").getText());
         }
      } catch (DocumentException e) {
         e.printStackTrace();
      }
   }
}

Dałoby to następujący wynik -

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

Current Element :student
Student roll no : 
First Name : dinkar
Last Name : kad
First Name : dinkar
Marks : 85

Current Element :student
Student roll no : 
First Name : Vaneet
Last Name : Gupta
First Name : vinni
Marks : 95

Current Element :student
Student roll no : 
First Name : jasvir
Last Name : singn
First Name : jazz
Marks : 90

Przykład demo

Oto wejściowy plik xml, który musimy przeanalizować -

<?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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>
   
   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</lastname>
      <nickname>jazz</nickname>
      <marks>90</marks>
   </student>
</class>

DOM4JQueryDemo.java

package com.tutorialspoint.xml;

import java.io.File;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;

public class DOM4JQueryDemo {

   public static void main(String[] args) {

      try {
         File inputFile = new File("input.txt");
         SAXReader reader = new SAXReader();
         Document document = reader.read( inputFile );

         System.out.println("Root element :" + document.getRootElement().getName());

         Element classElement = document.getRootElement();

         List<Node> nodes = document.selectNodes("/class/student[@rollno = '493']" );
         System.out.println("----------------------------");
         
         for (Node node : nodes) {
            System.out.println("\nCurrent Element :" 
               + node.getName());
            System.out.println("Student roll no : " 
               + node.valueOf("@rollno") );
            System.out.println("First Name : "
               + node.selectSingleNode("firstname").getText());
            System.out.println("Last Name : "
               + node.selectSingleNode("lastname").getText());
            System.out.println("First Name : "
               + node.selectSingleNode("nickname").getText());
            System.out.println("Marks : "
               + node.selectSingleNode("marks").getText());
         }
      } catch (DocumentException e) {
         e.printStackTrace();
      }
   }
}

Dałoby to następujący wynik -

Root element :class
----------------------------
Current Element :student
Student roll no : 493
First Name : Vaneet
Last Name : Gupta
First Name : vinni
Marks : 95

Przykład demo

Oto plik XML, który musimy utworzyć -

<?xml version = "1.0" encoding = "UTF-8"?>
<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 java.io.IOException;
import java.io.UnsupportedEncodingException;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

public class DOM4JCreateXMLDemo {

   public static void main(String[] args) {
      
      try {
         Document document = DocumentHelper.createDocument();
         Element root = document.addElement( "cars" );
         Element supercarElement = root.addElement("supercars")
            .addAttribute("company", "Ferrai");

         supercarElement.addElement("carname")
            .addAttribute("type", "Ferrari 101")
            .addText("Ferrari 101");

         supercarElement.addElement("carname")
            .addAttribute("type", "sports")
            .addText("Ferrari 202");

         // Pretty print the document to System.out
         OutputFormat format = OutputFormat.createPrettyPrint();
         XMLWriter writer;
         writer = new XMLWriter( System.out, format );
         writer.write( document );
      } catch (UnsupportedEncodingException e) {
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

Dałoby to następujący wynik -

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

Przykład demo

Oto plik XML, który musimy zmodyfikować -

<?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>Vaneet</firstname>
      <lastname>Gupta</lastname>
      <nickname>vinni</nickname>
      <marks>95</marks>
   </student>
   
   <student rollno = "593">
      <firstname>jasvir</firstname>
      <lastname>singn</lastname>
      <nickname>jazz</nickname>
      <marks>90</marks>
   </student>
</class>

DOM4jModifyXMLDemo.java

package com.tutorialspoint.xml;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Iterator;
import java.util.List;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

public class DOM4jModifyXMLDemo {

   public static void main(String[] args) {
   
      try {
         File inputFile = new File("input.txt");
         SAXReader reader = new SAXReader();
         Document document = reader.read( inputFile );

         Element classElement = document.getRootElement();

         List<Node> nodes = document.selectNodes("/class/student[@rollno = '493']" );
         
         for (Node node : nodes) {
            Element element = (Element)node;
            Iterator<Element> iterator = element.elementIterator("marks");

            while(iterator.hasNext()) {
               Element marksElement = (Element)iterator.next();
               marksElement.setText("80");
            }
         }

         // Pretty print the document to System.out
         OutputFormat format = OutputFormat.createPrettyPrint();
         XMLWriter writer;
         writer = new XMLWriter( System.out, format );
         writer.write( document );
      } catch (DocumentException e) {
         e.printStackTrace();
      } catch (UnsupportedEncodingException e) {         
         e.printStackTrace();
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

Dałoby to następujący wynik -

<?xml version = "1.0" encoding = "UTF-8"?>

<class> 
   <student rollno = "393"> 
      <firstname>dinkar</firstname>  
      <lastname>kad</lastname>  
      <nickname>dinkar</nickname>  
      <marks>85</marks> 
   </student>
   <student rollno = "493"> 
      <firstname>Vaneet</firstname>  
      <lastname>Gupta</lastname>  
      <nickname>vinni</nickname>  
      <marks>80</marks> 
   </student>  
   <student rollno = "593"> 
      <firstname>jasvir</firstname>  
      <lastname>singn</lastname>  
      <nickname>jazz</nickname>  
      <marks>90</marks> 
   </student> 
</class>