Ինչպես կարդալ և գրել XML ֆայլեր Java-ով


XML-ի ժողովրդականությունը վերջերս նվազել է, բայց դուք կարող եք երբեմն հանդիպել դրան, ուստի կարևոր է սովորել, թե ինչպես կարդալ և գրել XML ֆայլ:

XML ֆայլերը կարող են ծառայել տարբեր նպատակների, ներառյալ տվյալների պահպանումը: Նախքան JSON-ի հայտնի դառնալը, XML-ը նախընտրելի ձևաչափն էր կառուցվածքային տվյալների ներկայացման, պահպանման և փոխադրման համար:

Չնայած XML-ի ժողովրդականությունը նվազել է վերջին տարիներին, դուք կարող եք երբեմն հանդիպել դրան, ուստի կարևոր է սովորել, թե ինչպես աշխատել դրա հետ: Իմացեք, թե ինչպես օգտագործել DOM API-ն՝ Java-ով XML ֆայլեր կարդալու և գրելու համար:

Java-ում XML-ի մշակման պահանջները

Java Standard Edition (SE) ներառում է Java API-ն XML մշակման համար (JAXP), որը համապարփակ տերմին է, որը ներառում է XML մշակման շատ ասպեկտներ: Դրանք ներառում են.

  • DOM. Փաստաթղթի օբյեկտի մոդելը ներառում է դասեր XML օբյեկտների հետ աշխատելու համար, ինչպիսիք են տարրերը, հանգույցները և ատրիբուտները: DOM API-ն բեռնում է ամբողջական XML փաստաթուղթը հիշողության մեջ՝ մշակելու համար, ուստի այն լավ հարմար չէ մեծ XML ֆայլերի համար:
  • SAX. Պարզ API-ն XML-ի համար իրադարձությունների վրա հիմնված API է XML կարդալու համար: Այն գործարկում է իրադարձություններ՝ ի պատասխան XML բովանդակության, որը գտնում է ֆայլը վերլուծելիս: Այս մեթոդի հիշողության ծավալը ցածր է, բայց API-ի հետ աշխատելն ավելի դժվար է, քան DOM-ի հետ աշխատելը:
  • StAX. XML-ի հոսքային API-ն վերջերս լրացում է: Այն ապահովում է բարձր արդյունավետության հոսքի զտում, մշակում և XML-ի փոփոխում: Թեև այն խուսափում է ամբողջ XML փաստաթուղթը հիշողության մեջ բեռնելուց, այն ապահովում է ձգողական տիպի ճարտարապետություն, այլ ոչ թե իրադարձությունների վրա հիմնված ճարտարապետություն, ուստի ավելի հեշտ է կոդավորել, քան SAX API-ով:

Java-ում XML-ը մշակելու համար ձեզ հարկավոր է ներմուծել հետևյալ փաթեթները.

import javax.xml.parsers.*;
import javax.xml.transform.*;
import org.w3c.dom.*;

XML ֆայլի նմուշի պատրաստում

Նմուշի կոդը և դրա հիմքում ընկած հասկացությունները հասկանալու համար օգտագործեք Microsoft-ի XML ֆայլի այս նմուշը: Ահա մի հատված.

<?xml version="1.0"?>
<catalog>
  <book id="bk101">
    <author>Gambardella, Matthew</author>
    <title>XML Developer's Guide</title>
    <genre>Computer</genre>
    <price>44.95</price>
    <publish_date>2000-10-01</publish_date>
    <description>An in-depth look at creating applications
      with XML.</description>
  </book>
  <book id="bk102">
    <author>Ralls, Kim</author>
...snipped...

XML ֆայլի ընթերցում DOM API-ով

Եկեք դիտարկենք DOM API-ի միջոցով XML ֆայլը կարդալու համար անհրաժեշտ հիմնական քայլերը: Սկսեք ստեղծելով DocumentBuilder-ի օրինակ, որը դուք կօգտագործեք XML փաստաթուղթը վերլուծելու համար.

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

Այժմ կարող եք բեռնել ամբողջ փաստաթուղթը հիշողության մեջ՝ սկսած XML արմատային տարրից: Մեր օրինակում դա կատալոգտարրն է:

// XML file to read
File file = "<path_to_file>";
Document document = builder.parse(file);
Element catalog = document.getDocumentElement();

Եվ վերջ; դուք այժմ մուտք ունեք ամբողջ XML փաստաթուղթը՝ սկսած դրա արմատային տարրից՝ կատալոգ:

Տեղեկատվության արդյունահանում DOM API-ի միջոցով

Այժմ, երբ դուք ունեք XML արմատային տարր, կարող եք օգտագործել DOM API-ն՝ տեղեկատվության հետաքրքիր հատվածներ հանելու համար: Օրինակ, վերցրեք արմատային տարրի բոլոր bookերեխաները և շրջեք նրանց վրա: Նկատի ունեցեք, որ getChildNodes() վերադարձնում է բոլոր երեխաներին, ներառյալ տեքստը, մեկնաբանությունները և այլն: Ձեր նպատակի համար ձեզ անհրաժեշտ են միայն երեխայի տարրերը, որպեսզի կարողանաք բաց թողնել մյուսների վրայից:

NodeList books = catalog.getChildNodes();
for (int i = 0, ii = 0, n = books.getLength() ; i < n ; i++) {
  Node child = books.item(i);
  if ( child.getNodeType() != Node.ELEMENT_NODE )
    continue;
  Element book = (Element)child;
  // work with the book Element here
}

Ինչպե՞ս եք գտնում երեխայի հատուկ տարրը, հաշվի առնելով ծնողը: Ստեղծեք ստատիկ մեթոդ, որը վերադարձնում է առաջին համընկնող տարրը, եթե գտնվի, կամ՝ null: Ընթացակարգը ներառում է մանկական հանգույցների ցանկը ստանալը և դրանց միջով պտտվել՝ ընտրելով նշված անունով տարրերի հանգույցները:

static private Node findFirstNamedElement(Node parent,String tagName)
{
  NodeList children = parent.getChildNodes();
  for (int i = 0, in = children.getLength() ; i < in ; i++) {
    Node child = children.item(i);
    if (child.getNodeType() != Node.ELEMENT_NODE)
      continue;
    if (child.getNodeName().equals(tagName))
      return child;
  }
  return null;
}

Նկատի ունեցեք, որ DOM API-ն տարրի ներսում տեքստային բովանդակությունը վերաբերվում է որպես TEXT_NODE տեսակի առանձին հանգույց: Տեքստի բովանդակությունը կարող է բաղկացած լինել մի քանի հարակից տեքստային հանգույցներից, այնպես որ տարրի տեքստը ստանալու համար ձեզ անհրաժեշտ կլինի հատուկ մշակում.

static private String getCharacterData(Node parent)
{
  StringBuilder text = new StringBuilder();
  if ( parent == null )
    return text.toString();
  NodeList children = parent.getChildNodes();
  for (int k = 0, kn = children.getLength() ; k < kn ; k++) {
    Node child = children.item(k);
    if (child.getNodeType() != Node.TEXT_NODE)
      break;
    text.append(child.getNodeValue());
  }
  return text.toString();
}

Այս հարմար գործառույթներով զինված՝ նայեք այս կոդը՝ XML-ի նմուշից որոշ տեղեկություններ թվարկելու համար: Այն ցույց է տալիս մանրամասն տեղեկատվություն կատալոգում առկա յուրաքանչյուր գրքի համար.

NodeList books = catalog.getChildNodes();
for (int i = 0, ii = 0, n = books.getLength() ; i < n ; i++) {
  Node child = books.item(i);
  if (child.getNodeType() != Node.ELEMENT_NODE)
    continue;
  Element book = (Element)child;
  ii++;
  String id = book.getAttribute("id");
  String author = getCharacterData(findFirstNamedElement(child, "author"));
  String title = getCharacterData(findFirstNamedElement(child, "title"));
  String genre = getCharacterData(findFirstNamedElement(child, "genre"));
  String price = getCharacterData(findFirstNamedElement(child, "price"));
  String pubdate = getCharacterData(findFirstNamedElement(child, "pubdate"));
  String descr = getCharacterData(findFirstNamedElement(child, "description"));
  System.out.printf("%3d. book id = %s\n" +
    " author: %s\n" +
    " title: %s\n" +
    " genre: %s\n" +
    " price: %s\n" +
    " pubdate: %s\n" +
    " descr: %s\n",
    ii, id, author, title, genre, price, pubdate, descr);
}

Ահա կոդի քայլ առ քայլ բացատրությունը.

  1. Կոդը կրկնվում է catalog-ի՝ արմատային տարրի մանկական հանգույցների միջոցով:
  2. Յուրաքանչյուր երեխա հանգույցի համար, որը ներկայացնում է գիրք, այն ստուգում է, թե արդյոք հանգույցի տեսակը ELEMENT_NODE է: Եթե ոչ, ապա այն շարունակվում է հաջորդ կրկնությանը:
  3. Եթե երեխայի հանգույցը ELEMENT_NODE է, (Element)child այն ուղարկում է Element օբյեկտ:
  4. Այնուհետև ծածկագիրը գրքի տարրից հանում է տարբեր հատկանիշներ և նիշերի տվյալներ, այդ թվում՝ «id», «հեղինակ», «վերնագիր», «ժանր», «գին», «pub date» և «description»: Այն տպում է այս տվյալները՝ օգտագործելով System.out.printf մեթոդը:

Ահա թե ինչ տեսք ունի ելքը.

XML ելք գրելը Transform API-ի միջոցով

Java-ն ապահովում է XML Transform API՝ XML տվյալները փոխակերպելու համար: Մենք օգտագործում ենք այս API-ն ինքնության փոխակերպման հետ՝ արդյունք ստեղծելու համար: Որպես օրինակ՝ եկեք ավելացնենք նոր գիրք տարր վերը ներկայացված նմուշի կատալոգում:

Դուք կարող եք ձեռք բերել գրքի մանրամասները (հեղինակ, վերնագիր և այլն) արտաքին աղբյուրից, օրինակ՝ հատկությունների ֆայլից կամ տվյալների բազայից: Որպես օրինակ կարող եք օգտագործել հետևյալ հատկությունների ֆայլը.

id=bk113
author=Jane Austen
title=Pride and Prejudice
genre=Romance
price=6.99
publish_date=2010-04-01
description="It is a truth universally acknowledged, that a single man in possession of a good fortune must be in want of a wife." So begins Pride and Prejudice, Jane Austen's witty comedy of manners-one of the most popular novels of all time-that features splendidly civilized sparring between the proud Mr. Darcy and the prejudiced Elizabeth Bennet as they play out their spirited courtship in a series of eighteenth-century drawing-room intrigues.

Առաջին քայլը գոյություն ունեցող XML ֆայլը վերլուծելն է՝ օգտագործելով վերը ներկայացված մեթոդը.

File file = ...; // XML file to read
Document document = builder.parse(file);
Element catalog = document.getDocumentElement();

Այժմ դուք բեռնում եք տվյալները հատկությունների ֆայլից՝ օգտագործելով Java-ում տրամադրված Հատկություններ դասը: Կոդը բավականին պարզ է.

String propsFile = "<path_to_file>";
Properties props = new Properties();
try (FileReader in = new FileReader(propsFile)) {
  props.load(in);
}

Հատկությունները բեռնելուց հետո կարող եք առբերել այն արժեքները, որոնք ցանկանում եք ավելացնել հատկությունների ֆայլից.

String id = props.getProperty("id");
String author = props.getProperty("author");
String title = props.getProperty("title");
String genre = props.getProperty("genre");
String price = props.getProperty("price");
String publish_date = props.getProperty("publish_date");
String descr = props.getProperty("description");

Այժմ ստեղծեք դատարկ գիրք տարր:

Element book = document.createElement("book");
book.setAttribute("id", id);

Երեխաների տարրերը գրքում ավելացնելը չնչին է: Հարմարության համար դուք կարող եք հավաքել անհրաժեշտ տարրերի անունները Ցանկում և ավելացնել արժեքները օղակում:

List<String> elnames =Arrays.asList("author", "title", "genre", "price",
  "publish_date", "description");
for (String elname : elnames) {
  Element el = document.createElement(elname);
  Text text = document.createTextNode(props.getProperty(elname));
  el.appendChild(text);
  book.appendChild(el);
}
catalog.appendChild(book);

կատալոգ տարրում այժմ ավելացվել է նոր գիրք տարրը: Այժմ մնում է միայն դուրս գրել թարմացված XML-ը:

XML-ը գրելու համար ձեզ անհրաժեշտ է Transformer-ի օրինակ, որը կարող եք ստեղծել այսպես.

TransformerFactory tfact = TransformerFactory.newInstance();
Transformer tform = tfact.newTransformer();
tform.setOutputProperty(OutputKeys.INDENT, "yes");
tform.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "3");

Դուք կարող եք օգտագործել setOutputProperty() արդյունքի հետքագիծը պահանջելու համար:

Վերջնական քայլը փոխակերպումը կիրառելն է: Արդյունքը հայտնվում է ելքային հոսքում, System.out:

tform.transform(new DOMSource(document), new StreamResult(System.out));

Արդյունքը անմիջապես ֆայլում գրելու համար օգտագործեք հետևյալը.

tform.transform(new DOMSource(document), new StreamResult(new File("output.xml")));

Սա այն բոլոր քայլերն են, որոնք անհրաժեշտ են Java-ում XML ֆայլերը կարդալու և գրելու համար:

Այժմ դուք գիտեք, թե ինչպես կարդալ և գրել XML ֆայլեր Java-ով

Java-ով XML-ի վերլուծությունը և շահարկումը արժեքավոր հմտություն է, որը դուք հաճախ կօգտագործեք իրական աշխարհի ծրագրերում: Հատկապես օգտակար են DOM և Transform API-ները:

Հատկապես DOM-ի ըմբռնումը կենսական նշանակություն ունի, եթե նախատեսում եք հաճախորդի կողմից կոդ գրել վեբ հավելվածների կամ կայքերի համար: DOM-ի ինտերֆեյսը ունիվերսալ է, այնպես որ կարող եք աշխատել դրա հետ՝ օգտագործելով նմանատիպ կոդ լեզուներով, ինչպիսիք են Java-ն և JavaScript-ը: