JavaXML-クイックガイド

XMLとは何ですか?

XMLは、プレーンテキスト形式でデータを格納および転送するために設計された単純なテキストベースの言語です。Extensible MarkupLanguageの略です。以下は、XMLの顕著な機能の一部です。

  • XMLはマークアップ言語です。

  • XMLは、HTMLのようなタグベースの言語です。

  • XMLタグはHTMLのように事前定義されていません。

  • 独自のタグを定義できるため、拡張可能言語と呼ばれます。

  • XMLタグは、自己記述的であるように設計されています。

  • XMLは、データストレージとデータ転送に関するW3C勧告です。

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

利点

XMLが提供する利点は次のとおりです-

  • Technology agnostic−プレーンテキストであるため、XMLはテクノロジーに依存しません。これは、データストレージおよびデータ転送の目的で任意のテクノロジーで使用できます。

  • Human readable−XMLは単純なテキスト形式を使用します。人間が読める形式で理解できる形式です。

  • Extensible − XMLでは、カスタムタグを非常に簡単に作成して使用できます。

  • Allow Validation − XSDを使用すると、DTDおよびXML構造を簡単に検証できます。

短所

XMLを使用することの欠点は次のとおりです-

  • Redundant Syntax −通常、XMLファイルには多くの繰り返し用語が含まれています。

  • Verbose −冗長な言語であるため、XMLファイルサイズは送信とストレージのコストを増加させます。

XML解析とは、データにアクセスまたは変更するためにXMLドキュメントを調べることです。

XMLパーサーとは何ですか?

XMLパーサーは、XMLドキュメント内のデータにアクセスまたは変更する方法を提供します。Javaには、XMLドキュメントを解析するための複数のオプションがあります。以下は、XMLドキュメントの解析に一般的に使用されるさまざまなタイプのパーサーです。

  • Dom Parser −ドキュメントの完全なコンテンツをロードし、メモリ内に完全な階層ツリーを作成することにより、XMLドキュメントを解析します。

  • SAX Parser−イベントベースのトリガーでXMLドキュメントを解析します。ドキュメント全体をメモリにロードしません。

  • JDOM Parser − DOMパーサーと同様の方法で、ただしより簡単な方法でXMLドキュメントを解析します。

  • StAX Parser − SAXパーサーと同様の方法でXMLドキュメントを解析しますが、より効率的な方法で解析します。

  • XPath Parser −式に基づいてXMLドキュメントを解析し、XSLTと組み合わせて広く使用されます。

  • DOM4J Parser− Javaコレクションフレームワークを使用してXML、XPath、およびXSLTを解析するためのJavaライブラリ。DOM、SAX、およびJAXPのサポートを提供します。

オブジェクト指向の方法でXML解析を処理するために使用できるJAXBおよびXSLTAPIがあります。このチュートリアルの後続の章で、各パーサーについて詳しく説明します。

Document Object Model(DOM)は、World Wide Web Consortium(W3C)の公式推奨事項です。これは、プログラムがXMLドキュメントのスタイル、構造、およびコンテンツにアクセスして更新できるようにするインターフェイスを定義します。DOMをサポートするXMLパーサーは、このインターフェースを実装します。

いつ使用しますか?

−の場合はDOMパーサーを使用する必要があります

  • ドキュメントの構造について多くのことを知る必要があります。

  • XMLドキュメントの一部を移動する必要があります(たとえば、特定の要素を並べ替えることができます)。

  • XMLドキュメント内の情報を複数回使用する必要があります。

あなたは何を得るのですか?

DOMパーサーを使用してXMLドキュメントを解析すると、ドキュメントのすべての要素を含むツリー構造が返されます。DOMは、ドキュメントの内容と構造を調べるために使用できるさまざまな機能を提供します。

利点

DOMは、ドキュメント構造を操作するための一般的なインターフェイスです。その設計目標の1つは、1つのDOM準拠パーサー用に記述されたJavaコードを、変更を加えることなく、他のDOM準拠パーサーで実行することです。

DOMインターフェース

DOMはいくつかのJavaインターフェースを定義します。最も一般的なインターフェースは次のとおりです-

  • Node −DOMの基本データ型。

  • Element −扱うオブジェクトの大部分はElementsです。

  • Attr −要素の属性を表します。

  • Text −要素または属性の実際のコンテンツ。

  • Document−XMLドキュメント全体を表します。Documentオブジェクトは、DOMツリーと呼ばれることがよくあります。

一般的なDOMメソッド

DOMを使用する場合、頻繁に使用する方法がいくつかあります-

  • Document.getDocumentElement() −ドキュメントのルート要素を返します。

  • Node.getFirstChild() −指定されたノードの最初の子を返します。

  • Node.getLastChild() −指定されたノードの最後の子を返します。

  • Node.getNextSibling() −これらのメソッドは、指定されたノードの次の兄弟を返します。

  • Node.getPreviousSibling() −これらのメソッドは、指定されたノードの前の兄弟を返します。

  • Node.getAttribute(attrName) −指定されたノードについて、要求された名前の属性を返します。

JDOMを使用する手順

以下は、JDOMパーサーを使用してドキュメントを解析する際に使用される手順です。

  • XML関連のパッケージをインポートします。
  • DocumentBuilderを作成する
  • ファイルまたはストリームからドキュメントを作成する
  • ルート要素を抽出します
  • 属性を調べる
  • サブ要素を調べる

XML関連のパッケージをインポートする

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

DocumentBuilderを作成する

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

ファイルまたはストリームからドキュメントを作成する

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

ルート要素を抽出します

Element root = document.getDocumentElement();

属性を調べる

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

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

サブ要素を調べる

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

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

デモの例

これが解析する必要のある入力xmlファイルです-

<?xml version = "1.0"?>
<class>
   <student rollno = "393">
      <firstname>dinkar</firstname>
      <lastname>kad</lastname>
      <nickname>dinkar</nickname>
      <marks>85</marks>
   </student>
   
   <student rollno = "493">
      <firstname>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();
      }
   }
}

これにより、次の結果が生成されます-

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

デモの例

クエリする必要のある入力xmlファイルは次のとおりです-

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

QueryXmlFileDemo.java

package com.tutorialspoint.xml;

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

public class QueryXmlFileDemo {

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

これにより、次の結果が生成されます-

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

Current Element :
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 :

デモの例

作成する必要のあるXMLは次のとおりです-

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

CreateXmlFileDemo.java

package com.tutorialspoint.xml;

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

public class CreateXmlFileDemo {

   public static void main(String argv[]) {

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

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

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

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

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

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

これにより、次の結果が生成されます-

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

<cars>
   <supercars company = "Ferrari">
      <carname type = "formula one">Ferrari 101</carname>
      <carname type = "sports">Ferrari 202</carname>
   </supercars>
</cars>

デモの例

変更する必要のある入力xmlファイルは次のとおりです-

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

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

これにより、次の結果が生成されます-

-----------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)は、XMLドキュメント用のイベントベースのパーサーです。DOMパーサーとは異なり、SAXパーサーは解析ツリーを作成しません。SAXはXMLのストリーミングインターフェイスです。つまり、SAXを使用するアプリケーションは、要素と属性を処理しているXMLドキュメントに関するイベント通知を、ドキュメントの先頭から始まり、 ROOT要素。

  • XMLドキュメントを上から下に読み取り、整形式のXMLドキュメントを構成するトークンを認識します。

  • トークンは、ドキュメントに表示されるのと同じ順序で処理されます。

  • パーサーが発生したトークンの性質をアプリケーションプログラムに報告します。

  • アプリケーションプログラムは、パーサーに登録する必要のある「イベント」ハンドラーを提供します。

  • トークンが識別されると、ハンドラーのコールバックメソッドが関連情報とともに呼び出されます。

いつ使用しますか?

−の場合はSAXパーサーを使用する必要があります

  • XMLドキュメントは上から下に直線的に処理できます。

  • ドキュメントは深くネストされていません。

  • DOMツリーが大量のメモリを消費する非常に大きなXMLドキュメントを処理しています。一般的なDOM実装では、10バイトのメモリを使用して1バイトのXMLを表します。

  • 解決すべき問題は、XMLドキュメントの一部のみに関係します。

  • データはパーサーに表示されるとすぐに利用できるため、SAXはストリームを介して到着するXMLドキュメントに適しています。

SAXのデメリット

  • XMLドキュメントは順方向のみで処理されるため、ランダムアクセスはありません。

  • パーサーが確認したデータを追跡したり、アイテムの順序を変更したりする必要がある場合は、コードを記述してデータを自分で保存する必要があります。

ContentHandlerインターフェース

このインターフェイスは、SAXパーサーがXMLドキュメントのコンポーネントをアプリケーションプログラムに通知するために使用するコールバックメソッドを指定します。

  • void startDocument() −ドキュメントの冒頭で呼び出されます。

  • void endDocument() −ドキュメントの最後に呼び出されます。

  • void startElement(String uri, String localName, String qName, Attributes atts) −要素の先頭で呼び出されます。

  • void endElement(String uri, String localName,String qName) −要素の最後で呼び出されます。

  • void characters(char[] ch, int start, int length) −文字データが検出されたときに呼び出されます。

  • void ignorableWhitespace( char[] ch, int start, int length) − DTDが存在し、無視できる空白が検出された場合に呼び出されます。

  • void processingInstruction(String target, String data) −処理命令が認識されたときに呼び出されます。

  • void setDocumentLocator(Locator locator)) −ドキュメント内の位置を識別するために使用できるロケーターを提供します。

  • void skippedEntity(String name) −未解決のエンティティが検出されたときに呼び出されます。

  • void startPrefixMapping(String prefix, String uri) −新しい名前空間マッピングが定義されたときに呼び出されます。

  • void endPrefixMapping(String prefix) −名前空間定義がそのスコープを終了したときに呼び出されます。

属性インターフェース

このインターフェースは、要素に接続された属性を処理するためのメソッドを指定します。

  • int getLength() −属性の数を返します。

  • String getQName(int index)

  • String getValue(int index)

  • String getValue(String qname)

デモの例

解析する必要のある入力xmlファイルは次のとおりです-

<?xml version = "1.0"?>
<class>
   <student rollno = "393">
      <firstname>dinkar</firstname>
      <lastname>kad</lastname>
      <nickname>dinkar</nickname>
      <marks>85</marks>
   </student>
   
   <student rollno = "493">
      <firstname>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;
      }
   }
}

これにより、次の結果が生成されます-

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

デモの例

これが、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;
      }
   }
}

これにより、次の結果が生成されます-

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.

デモの例

</ marks>タグの最後に<Result> Pass <Result />を追加して変更する必要がある入力XMLファイルは次のとおりです。

<?xml version = "1.0"?>
<class>
   <student rollno = "393">
      <firstname>dinkar</firstname>
      <lastname>kad</lastname>
      <nickname>dinkar</nickname>
      <marks>85</marks>
   </student>
   
   <student rollno = "493">
      <firstname>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");
      }
   }
}

これにより、次の結果が生成されます-

<?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は、XMLドキュメントを解析するためのオープンソースのJavaベースのライブラリです。これは通常、Java開発者向けのAPIです。これはJavaに最適化されており、ListやArraysなどのJavaコレクションを使用します。

JDOMはDOMおよびSAXAPIと連携し、2つの長所を組み合わせています。メモリフットプリントが低く、SAXとほぼ同じ速度です。

環境設定

JDOMパーサーを使用するには、アプリケーションのクラスパスにjdom.jarが含まれている必要があります。jdom-2.0.5.zipをダウンロードします。

いつ使用しますか?

−の場合はJDOMパーサーを使用する必要があります

  • XMLドキュメントの構造について多くのことを知る必要があります。

  • XMlドキュメントの一部を移動する必要があります(たとえば、特定の要素を並べ替えることができます)。

  • XMLドキュメント内の情報を複数回使用する必要があります。

  • あなたはJava開発者であり、Javaに最適化されたXMLの解析を活用したいと考えています。

あなたは何を得るのですか?

JDOMパーサーを使用してXMLドキュメントを解析すると、アプリケーションのメモリフットプリントに影響を与えることなく、ドキュメントのすべての要素を含むツリー構造を柔軟に取り戻すことができます。

JDOMは、ドキュメントが適切に構造化されており、その構造がわかっている場合に、XMLドキュメントの内容と構造を調べるために使用できるさまざまなユーティリティ関数を提供します。

利点

JDOMは、Java開発者にXML解析コードの柔軟性と簡単な保守性を提供します。軽量で迅速なAPIです。

JDOMクラス

JDOMはいくつかのJavaクラスを定義します。最も一般的なクラスは次のとおりです-

  • Document−XMLドキュメント全体を表します。Documentオブジェクトは、DOMツリーと呼ばれることがよくあります。

  • Element−XML要素を表します。Elementオブジェクトには、その子要素、テキスト、属性、および名前空間を操作するメソッドがあります。

  • Attribute−要素の属性を表します。属性には、属性の値を取得および設定するメソッドがあります。親と属性のタイプがあります。

  • Text −XMLタグのテキストを表します。

  • Comment −XMLドキュメント内のコメントを表します。

一般的なJDOMメソッド

JDOMを使用する場合、頻繁に使用する方法がいくつかあります-

  • SAXBuilder.build(xmlSource)() −xmlソースからJDOMドキュメントを作成します。

  • Document.getRootElement() −XMLのルート要素を取得します。

  • Element.getName() −XMLノードの名前を取得します。

  • Element.getChildren() −要素のすべての直接の子ノードを取得します。

  • Node.getChildren(Name) −指定された名前のすべての直接子ノードを取得します。

  • Node.getChild(Name) −指定された名前の最初の子ノードを取得します。

JDOMを使用する手順

以下は、JDOMパーサーを使用してドキュメントを解析する際に使用される手順です。

  • XML関連のパッケージをインポートします。
  • SAXBuilderを作成する
  • ファイルまたはストリームからドキュメントを作成する
  • ルート要素を抽出します
  • 属性を調べる
  • サブ要素を調べる

XML関連のパッケージをインポートする

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

DocumentBuilderを作成する

SAXBuilder saxBuilder = new SAXBuilder();

ファイルまたはストリームからドキュメントを作成する

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

ルート要素を抽出します

Element classElement = document.getRootElement();

属性を調べる

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

サブ要素を調べる

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

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

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

デモの例

解析する必要のある入力xmlファイルは次のとおりです-

<?xml version = "1.0"?>
<class>
   <student rollno = "393">
      <firstname>dinkar</firstname>
      <lastname>kad</lastname>
      <nickname>dinkar</nickname>
      <marks>85</marks>
   </student>
   
   <student rollno = "493">
      <firstname>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();
      }
   }
}

これにより、次の結果が生成されます-

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

デモの例

クエリする必要のある入力xmlファイルは次のとおりです-

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

QueryXmlFileDemo.java

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

これにより、次の結果が生成されます-

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

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

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

デモの例

作成する必要のあるXMLファイルは次のとおりです-

<?xml version = "1.0" encoding = "UTF-8"?>
<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();
      }
   }
}

これにより、次の結果が生成されます-

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

デモの例

変更する必要のある入力テキストファイルは次のとおりです-

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

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

これにより、次の結果が生成されます-

<?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は、SAXパーサーと同様の方法でXMLドキュメントを解析するJavaベースのAPIです。しかし、2つのAPIには2つの大きな違いがあります-

  • StAXはPULLAPIですが、SAXはPUSHAPIです。つまり、StAXパーサーの場合、クライアントアプリケーションはStAXパーサーに必要なときにXMLから情報を取得するように要求する必要があります。ただし、SAXパーサーの場合、SAXパーサーがクライアントアプリケーションに情報が利用可能であることを通知するときに、クライアントアプリケーションは情報を取得する必要があります。

  • StAX APIは、XMLドキュメントの読み取りと書き込みを行うことができます。SAX APIを使用すると、XMLファイルは読み取りのみが可能です。

環境設定

StAXパーサーを使用するには、アプリケーションのクラスパスにstax.jarが含まれている必要があります。

StAXAPIの機能は次のとおりです-

  • XMLドキュメントを上から下に読み取り、整形式のXMLドキュメントを構成するトークンを認識します。

  • トークンは、ドキュメントに表示されるのと同じ順序で処理されます。

  • パーサーが発生したトークンの性質をアプリケーションプログラムに報告します。

  • アプリケーションプログラムは、イテレータとして機能し、イベントを反復処理して必要な情報を取得する「イベント」リーダーを提供します。利用可能な別のリーダーは、XMLノードへのポインターとして機能する「カーソル」です。

  • イベントが識別されると、XML要素をイベントオブジェクトから取得して、さらに処理することができます。

いつ使用しますか?

−の場合はStAXパーサーを使用する必要があります

  • XMLドキュメントは上から下に直線的に処理できます。

  • ドキュメントは深くネストされていません。

  • DOMツリーが大量のメモリを消費する非常に大きなXMLドキュメントを処理しています。一般的なDOM実装では、10バイトのメモリを使用して1バイトのXMLを表します。

  • 解決すべき問題は、XMLドキュメントの一部のみに関係します。

  • データはパーサーに表示されるとすぐに利用できるため、StAXはストリームを介して到着するXMLドキュメントに適しています。

SAXのデメリット

  • XMLドキュメントは順方向のみで処理されるため、ランダムアクセスはありません。

  • パーサーが見たデータ、またはパーサーがアイテムの順序を変更した場所を追跡する必要がある場合は、コードを記述してデータを自分で保存する必要があります。

XMLEventReaderクラス

このクラスは、XMLドキュメントの解析中に発生したイベントを反復処理するために使用できるイベントの反復子を提供します。

  • StartElement asStartElement() −要素の値と属性を取得するために使用されます。

  • EndElement asEndElement() −要素の最後で呼び出されます。

  • Characters asCharacters() − CDATA、空白などの文字を取得するために使用できます。

XMLEventWriterクラス

このインターフェースは、イベントを作成するためのメソッドを指定します。

  • add(Event event) −要素を含むイベントをXMLに追加します。

XMLStreamReaderクラス

このクラスは、XMLドキュメントの解析中に発生したイベントを反復処理するために使用できるイベントの反復子を提供します。

  • int next() −次のイベントを取得するために使用されます。

  • boolean hasNext() −さらにイベントが存在するかどうかを確認するために使用されます。

  • String getText() −要素のテキストを取得するために使用されます。

  • String getLocalName() −要素の名前を取得するために使用されます。

XMLStreamWriterクラス

このインターフェースは、イベントを作成するためのメソッドを指定します。

  • writeStartElement(String localName) −指定された名前の開始要素を追加します。

  • writeEndElement(String localName) −指定された名前の終了要素を追加します。

  • writeAttribute(String localName, String value) −属性を要素に書き込みます。

デモの例

これが解析する必要のある入力xmlファイルです-

<?xml version = "1.0"?>
<class>
   <student rollno = "393">
      <firstname>dinkar</firstname>
      <lastname>kad</lastname>
      <nickname>dinkar</nickname>
      <marks>85</marks>
   </student>
   
   <student rollno = "493">
      <firstname>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();
      }
   }
}

これにより、次の結果が生成されます-

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

デモの例

これが解析する必要のある入力xmlファイルです-

<?xml version = "1.0"?>
<class>
   <student rollno = "393">
      <firstname>dinkar</firstname>
      <lastname>kad</lastname>
      <nickname>dinkar</nickname>
      <marks>85</marks>
   </student>
   
   <student rollno = "493">
      <firstname>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();
      }
   }
}

これにより、次の結果が生成されます-

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

デモの例

作成する必要のあるXMLは次のとおりです-

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

StAXCreateXMLDemo.java

package com.tutorialspoint.xml;

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

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

public class StAXCreateXMLDemo {

   public static void main(String[] args) {

      try {
         StringWriter stringWriter = new StringWriter();

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

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

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

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

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

         stringWriter.close();

         System.out.println(xmlString);

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

これにより、次の結果が生成されます-

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

デモの例

変更する必要のあるXMLは次のとおりです-

<?xml version = "1.0"?>
<class>
   <student rollno = "393">
      <firstname>dinkar</firstname>
      <lastname>kad</lastname>
      <nickname>dinkar</nickname>
      <marks>85</marks>
   </student>
   
   <student rollno = "493">
      <firstname>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();
      }
   }
}

これにより、次の結果が生成されます-

<?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は、World Wide Web Consortium(W3C)の公式推奨事項です。XMLファイル内の情報を検索するための言語を定義します。XMLドキュメントの要素と属性をトラバースするために使用されます。XPathは、XMLドキュメントから関連情報を照会するために使用できるさまざまなタイプの式を提供します。

XPathとは何ですか?

  • Structure Definations − XPathは、要素、属性、テキスト、名前空間、処理命令、コメント、ドキュメントノードなどのXMLドキュメントの部分を定義します。

  • Path Expressions − XPathは、XMLドキュメント内のノードの選択やノードのリストなどの強力なパス式を提供します。

  • Standard Functions − XPathは、文字列値、数値、日付と時刻の比較、ノードとQNameの操作、シーケンス操作、ブール値などを操作するための標準関数の豊富なライブラリを提供します。

  • Major part of XSLT − XPathはXSLT標準の主要な要素の1つであり、XSLTドキュメントを操作するにはXPathに関する十分な知識が必要です。

  • W3C recommendation − XPathは、World Wide Web Consortium(W3C)の公式推奨事項です。

XPath式

XPathは、パス式を使用して、XMLドキュメントからノードまたはノードのリストを選択します。以下は、XMLドキュメントから任意のノード/ノードのリストを選択するための便利なパスと式のリストです。

シニア番号 表現と説明
1

node-name

指定された名前「nodename」を持つすべてのノードを選択します

2

/

選択はルートノードから始まります

3

//

選択は、選択に一致する現在のノードから開始されます

4

.

現在のノードを選択します

5

..

現在のノードの親を選択します

6

@

属性を選択します

7

student

Example −「student」という名前のすべてのノードを選択します

8

class/student

Example −クラスの子であるすべての学生要素を選択します

9

//student

ドキュメント内のどこにいても、すべての学生要素を選択します

述語

述語は、特定のノードまたは特定の値を含むノードを見つけるために使用され、[...]を使用して定義されます。

結果
/ class / student [1] class要素の子である最初のstudent要素を選択します。
/ class / student [last()] class要素の子である最後のstudent要素を選択します。
/ class / student [last()-1] class要素の子である最後の1つのstudent要素を選択します。
//学生[@ rollno = '493'] 値が「493」のrollnoという名前の属性を持つすべての学生要素を選択します

XPathを使用する手順

以下は、XPathパーサーを使用してドキュメントを解析する際に使用される手順です。

  • XML関連のパッケージをインポートします。

  • DocumentBuilderを作成します。

  • ファイルまたはストリームからドキュメントを作成します。

  • XpathオブジェクトとXPathパス式を作成します。

  • を使用してXPath式をコンパイルします XPath.compile() コンパイルされた式を評価してノードのリストを取得します。 XPath.evaluate()

  • ノードのリストを繰り返し処理します。

  • 属性を調べます。

  • サブ要素を調べます。

XML関連のパッケージをインポートする

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

DocumentBuilderを作成する

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

ファイルまたはストリームからドキュメントを作成する

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

XPathを構築する

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

パス式を準備して評価する

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

NodeListを反復処理します

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

属性を調べる

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

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

サブ要素を調べる

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

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

デモの例

解析する必要のある入力テキストファイルは次のとおりです-

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

これにより、次の結果が生成されます-

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

デモの例

クエリする必要のある入力テキストファイルは次のとおりです-

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

これにより、次の結果が生成されます-

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は、XMLドキュメントを解析するためのオープンソースのJavaベースのライブラリです。これは、柔軟性が高く、メモリ効率の高いAPIです。これはJavaに最適化されており、ListやArraysなどのJavaコレクションを使用します。

DOM4Jは、DOM、SAX、XPath、およびXSLTで動作します。非常に少ないメモリフットプリントで大きなXMLドキュメントを解析できます。

環境設定

DOM4Jパーサーを使用するには、アプリケーションのクラスパスにdom4j-1.6.1.jarとjaxen.jarが含まれている必要があります。dom4j-1.6.1.zipをダウンロードします。

いつ使用しますか?

−の場合はDOM4Jパーサーを使用する必要があります

  • XMLドキュメントの構造について多くのことを知る必要があります。

  • XMLドキュメントの一部を移動する必要があります(たとえば、特定の要素を並べ替えることができます)。

  • XMLドキュメント内の情報を複数回使用する必要があります。

  • あなたはJava開発者であり、Javaに最適化されたXMLの解析を活用したいと考えています。

あなたは何を得るのですか?

DOM4Jパーサーを使用してXMLドキュメントを解析すると、アプリケーションのメモリフットプリントに影響を与えることなく、ドキュメントのすべての要素を含むツリー構造を柔軟に取り戻すことができます。

DOM4Jは、ドキュメントが適切に構造化されており、その構造がわかっている場合に、XMLドキュメントの内容と構造を調べるために使用できるさまざまなユーティリティ関数を提供します。

DOM4Jは、XPath式を使用してXMLドキュメント内を移動します。

利点

DOM4Jは、Java開発者にXML解析コードの柔軟性と簡単な保守性を提供します。軽量で迅速なAPIです。

DOM4Jクラス

DOM4JはいくつかのJavaクラスを定義します。最も一般的なクラスは次のとおりです-

  • Document−XMLドキュメント全体を表します。Documentオブジェクトは、DOMツリーと呼ばれることがよくあります。

  • Element−XML要素を表します。Elementオブジェクトには、その子要素、テキスト、属性、および名前空間を操作するメソッドがあります。

  • Attribute−要素の属性を表します。属性には、属性の値を取得および設定するメソッドがあります。親と属性のタイプがあります。

  • Node −要素、属性、またはProcessingInstructionを表します。

一般的なDOM4Jメソッド

DOM4Jを使用している場合、頻繁に使用する方法がいくつかあります-

  • SAXReader.read(xmlSource)() −XMLソースからDOM4Jドキュメントを作成します。

  • Document.getRootElement() −XMLドキュメントのルート要素を取得します。

  • Element.node(index) −要素内の特定のインデックスでXMLノードを取得します。

  • Element.attributes() −要素のすべての属性を取得します。

  • Node.valueOf(@Name) −指定された要素名を持つ属性の値を取得します。

DOM4Jを使用する手順

以下は、DOM4Jパーサーを使用してドキュメントを解析する際に使用される手順です。

  • XML関連のパッケージをインポートします。

  • SAXReaderを作成します。

  • ファイルまたはストリームからドキュメントを作成します。

  • document.selectNodes()を呼び出して、XPath式を使用して必要なノードを取得します

  • ルート要素を抽出します。

  • ノードのリストを繰り返し処理します。

  • 属性を調べます。

  • サブ要素を調べます。

XML関連のパッケージをインポートする

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

DocumentBuilderを作成する

SAXBuilder saxBuilder = new SAXBuilder();

ファイルまたはストリームからドキュメントを作成する

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

ルート要素を抽出します

Element classElement = document.getRootElement();

属性を調べる

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

サブ要素を調べる

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

デモの例

これが解析する必要のある入力xmlファイルです-

<?xml version = "1.0"?>
<class>
   <student rollno = "393">
      <firstname>dinkar</firstname>
      <lastname>kad</lastname>
      <nickname>dinkar</nickname>
      <marks>85</marks>
   </student>
   
   <student rollno = "493">
      <firstname>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();
      }
   }
}

これにより、次の結果が生成されます-

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

デモの例

これが解析する必要のある入力xmlファイルです-

<?xml version = "1.0"?>
<class>
   <student rollno = "393">
      <firstname>dinkar</firstname>
      <lastname>kad</lastname>
      <nickname>dinkar</nickname>
      <marks>85</marks>
   </student>
   
   <student rollno = "493">
      <firstname>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();
      }
   }
}

これにより、次の結果が生成されます-

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

デモの例

作成する必要のあるXMLは次のとおりです-

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

これにより、次の結果が生成されます-

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

デモの例

変更する必要のあるXMLは次のとおりです-

<?xml version = "1.0"?>
<class>
   <student rollno = "393">
      <firstname>dinkar</firstname>
      <lastname>kad</lastname>
      <nickname>dinkar</nickname>
      <marks>85</marks>
   </student>
   
   <student rollno = "493">
      <firstname>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();
      }
   }
}

これにより、次の結果が生成されます-

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