Try English version of Quizful



Раздаем бесплатные Q! подробности в группе Quizful.Alpha-test
Партнеры
Рекрутерам: Прескрининг кандидатов about
Топ контрибуторов
loading
loading
Знаете ли Вы, что

Вы можете подписаться на RSS ленту новых тестов сервиса Quizful, в том числе и отдельно по каждой категории

Лента обновлений
ссылка 20:57:36
Комментарий от Recrut_rf:
Спасибо, сохранил функцию, может пригодится когда - ни...
ссылка 20:53:59
Добавлен вопрос в тест ASP.NET - Основы
ссылка 08:41:09
Комментарий от Krosster:
Гарний сайт для новачків. Правда деякі питання підступн...
ссылка Apr 22 22:06
Добавлен вопрос в тест SQL - Средний уровень
ссылка Apr 22 10:13
Комментарий от Entrery:
вроде выбрал ООП в сишарпе, а тут вопросы по джаве...
Статистика

Тестов: 153, вопросов: 8596. Пройдено: 402470 / 1961087.

Начало работы с XML в Java

head tail Статья
категория
Java
дата05.03.2014
авторYuriyDunko
голосов20

DTD и XSD - языки описания структуры XML документа (что и как описывает документ).

DTD описывает схему документа для конкретного языка разметки посредством набора объявлений (объектов-параметров, элементов и атрибутов), которые описывают его класс (или тип) с точки зрения синтаксических ограничений этого документа. Также DTD может объявлять конструкции, которые всегда необходимы для определения структуры документа, но, зато, могут влиять на интерпретацию определенных документов.

Сейчас идёт отказ от использования DTD в XML-технологии (но они до сих пор активно используются).
Преимущество: описание может находится в самом xml.

Пример:


<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE people_list [
  <!ELEMENT people_list (person)*>
  <!ELEMENT person (name, birthdate?, gender?, socialsecuritynumber?)>
  <!ELEMENT name (#PCDATA)>
  <!ELEMENT birthdate (#PCDATA)>
  <!ELEMENT gender (#PCDATA)>
  <!ELEMENT socialsecuritynumber (#PCDATA)>
]>
<people_list>
  <person>
    <name>Marla Bloggs</name>
    <birthdate>2013-01-22</birthdate>
    <gender>Female</gender>
  </person>
</people_list>

"XSD" (XML Schema definition) (short XML Schema) — язык описания структуры XML-документа. Спецификация XML Schema является рекомендацией W3C.

Как большинство языков описания XML, XML Schema была задумана для определения правил, которым должен подчиняться документ. Но, в отличие от других языков, XML Schema была разработана так, чтобы её можно было использовать в создании программного обеспечения для обработки документов XML.

После проверки документа на соответствие XML Schema, читающая программа может создать модель данных документа.
Приймущество: описание включает схемы, и может быть удалённым (URL) и общим Пример:


"SimpleAddress.xsd"
<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Address">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Recipient" type="xs:string" />
        <xs:element name="House" type="xs:string" />
        <xs:element name="Street" type="xs:string" />
        <xs:element name="Town" type="xs:string" />
        <xs:element name="County" type="xs:string" minOccurs="0" />
        <xs:element name="PostCode" type="xs:string" />
        <xs:element name="Country">
          <xs:simpleType>
            <xs:restriction base="xs:string">
              <xs:enumeration value="FR" />
              <xs:enumeration value="DE" />
              <xs:enumeration value="ES" />
              <xs:enumeration value="UK" />
              <xs:enumeration value="US" />
            </xs:restriction>
          </xs:simpleType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

"file.xml"
<?xml version="1.0" encoding="utf-8"?>
<Address xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
         xsi:noNamespaceSchemaLocation="SimpleAddress.xsd">
  <Recipient>Mr. Walter C. Brown</Recipient>
  <House>49</House>
  <Street>Featherstone Street</Street>
  <Town>LONDON</Town>
  <PostCode>EC1Y 8SY</PostCode>
  <Country>UK</Country>
</Address>

JAXP - сам читает схемы и определят правильность (validation) документа, вне зависимости от подхода к анализу. Первым делом читаются мето данные документа. При их отсутствии будет выведено предупреждение в (System.err).

Links:
http://ru.wikipedia.org/wiki/DTD
http://ru.wikipedia.org/wiki/XML_Schema

Правильно построенные и действительные документы XML

Стандартом определены два уровня правильности документа XML:

Правильно построенный (англ. well-formed). Правильно построенный документ соответствует всем общим правилам синтаксиса XML, применимым к любому XML-документу. И если, например, начальный тег не имеет соответствующего ему конечного тега, то это неправильно построенный документ XML. Документ, который неправильно построен, не может считаться документом XML; XML-процессор (парсер) не должен обрабатывать его обычным образом и обязан классифицировать ситуацию как фатальная ошибка.

Действительный (англ. valid). Действительный документ дополнительно соответствует некоторым семантическим правилам. Это более строгая дополнительная проверка корректности документа на соответствие заранее определённым, но уже внешним правилам, в целях минимизации количества ошибок, например, структуры и состава данного, конкретного документа или семейства документов. Эти правила могут быть разработаны как самим пользователем, так и сторонними разработчиками, например, разработчиками словарей или стандартов обмена данными. Обычно такие правила хранятся в специальных файлах — схемах, где самым подробным образом описана структура документа, все допустимые названия элементов, атрибутов и многое другое. И если документ, например, содержит не определённое заранее в схемах название элемента, то XML-документ считается недействительным; проверяющий XML-процессор (валидатор) при проверке на соответствие правилам и схемам обязан (по выбору пользователя) сообщить об ошибке.

Данные два понятия не имеют достаточно устоявшегося стандартизированного перевода на русский язык, особенно понятие valid, которое можно также перевести, как имеющий силу, правомерный, надёжный, годный, или даже проверенный на соответствие правилам, стандартам, законам. Некоторые программисты применяют в обиходе устоявшуюся кальку «Валидный».

XML — это описанная в текстовом формате иерархическая структура, предназначенная для хранения любых данных. Визуально структура может быть представлена как дерево элементов. Элементы XML описываются тегами.

Пример:

<?xml version="1.0" encoding="UTF-8"?>
<recipe name="Пицца" preptime="5" cooktime="180">
  <title>Тесто для пиццы</title>
  <ingredient amount="3" unit="стакан">Вода теплая</ingredient>
  <ingredient amount="0.25" unit="грамм">Мука</ingredient>
  <ingredient amount="1.5" unit="грамм">Дрожжи сухие</ingredient>
  <ingredient amount="1" unit="чайная ложка">Оливковое масло</ingredient>
  <instructions>
   <step>Муку просеять в большую миску и сделать внутри углубление - кратер.</step>
   <step>Всыпать в углубление дрожжи и добавить немного теплой воды. дать постоять 5-7 минут, чтобы дрожжи ожили и начали работу.</step>
   <!-- <step>Почитать вчерашнюю газету.</step> - это сомнительный шаг... -->
   <step>Добавить соль и оливковое масло и начать размешивать вилкой, постепенно добавляя теплую воду и замешивая тесто.</step>
  </instructions>
</recipe>

Первая строка XML-документа называется объявление XML (англ. XML declaration) — это строка, указывающая версию XML. В версии 1.0 объявление XML может быть опущено, в версии 1.1 оно обязательно. Также здесь может быть указана кодировка символов и наличие внешних зависимостей.

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

Важнейшее обязательное синтаксическое требование заключается в том, что документ имеет только один корневой элемент (англ. root element), как приведено в предыдущем примере.

В любом месте дерева может быть размещен элемент-комментарий. XML-комментарии размещаются внутри специального тега, начинающегося с символов . Два знака дефис (--) внутри комментария присутствовать не могут.

<!-- Это комментарий. -->
Но не внутри объявления тега!

Links: http://ru.wikipedia.org/wiki/XML

Практика

DOM - это есть объектная модель документа. XML документ представляет собой набор тегов – узлов. Каждый узел может иметь неограниченное количество дочерних узлов. Каждый дочерний тоже может содержать много-много потомков или не содержать их вовсе. Таким образом получается некое дерево. Так вот DOM представляет собой всё это дерево в виде специальных объектов Node. Каждый Node соответствует своему XML-тегу. Каждый Node содержит полную информацию о том, что это за тег, какие он имеет атрибуты, какие дочерние узлы содержит внутри себя и так далее. На самой вершине этой иерархии находится Document. (подробней о абстрактной моделе http://ru.wikipedia.org/wiki/Document_Object_Model)

Пимечание: одно из достоинств DOM перед SAX - скорость обработки информации, но чем больше объем переработанной информации, тем дольше начинает работать DOM.

Анализ документа с помощью JAXP, используя DOM - войдём в каждую ветвь дерева и обработаем её.


import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document; // обратите внимание !
public class MainClass {
  public static void main(String[] args) throws Exception {
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); //создали фабрику строителей, сложный и грамосткий процесс (по реже выполняйте это действие)
    // f.setValidating(false); // не делать проверку валидации
    DocumentBuilder db = dbf.newDocumentBuilder(); // создали конкретного строителя документа
    Document doc = db.parse(new File(/*"sample.xml"*/args[0])); // стооитель построил документ
	//Document - тоже является нодом, и импленментирует методы
    visit(doc, 0);
  }
  public static void visit(Node node, int level) {
    NodeList list = node.getChildNodes();
    for (int i = 0; i < list.getLength(); i++) {
      Node childNode = list.item(i); // текущий нод
      process(childNode, level + 1); // обработка
      visit(childNode, level + 1); // рекурсия
    }
  }
  public static void process(Node node, int level) {
    for (int i = 0; i < level; i++) {
      System.out.print('\t');
    }
    System.out.print(node.getNodeName());
    if (node instanceof Element){
        Element e = (Element) node;
        // работаем как с элементом (у него есть атрибуты и схема)
    }
    System.out.println();
  }
}
// Создание документа
 public static void main(String[] argv) throws Exception {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    DOMImplementation impl = builder.getDOMImplementation(); // более сложный, но и более гибкий способ создания документов
    Document doc = impl.createDocument(null, // namespaceURI
                                       null, // qualifiedName
                                       null); // doctype
    Element e1 = doc.createElement("api");
    doc.appendChild(e1);
    Element e2 = doc.createElement("java");
    e2.setAttribute("url", "http://www.quizful.net");
    e1.appendChild(e2);
}

Фичи:

  • Копирование документов
  • 
      public static void copyDocument(Document source, Document target){
        Node node = target.importNode(source.getDocumentElement(), true);
        target.getDocumentElement().appendChild(node);
      }
    
  • Создать новый документ документов
  • 
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        DocumentBuilder db = dbf.newDocumentBuilder();
        Document doc = db.newDocument();
    
  • Документ в стоке
  • 
        Document doc = db.parse(new InputSource(new StringReader(xmlString)));
    
  • Форматированный вывод документа
  • 
        DOMSource source = new DOMSource(doc);
        StreamResult result = new StreamResult(System.out);//Может быть любой поток вывода (файл, сокет ....)
        TransformerFactory transFactory = TransformerFactory.newInstance(); // Об этом подробней в 4 вопросе
        Transformer transformer = transFactory.newTransformer();
        transformer.transform(source, result);
    

SAX (Simple API for XML) - событийно-ориентированное API.

Последовательный разбор XML-документа SAX-обработчиком обычно производится по следующей схеме :

  • Загрузить документ, установить обработчики событий, начать просмотр его содержимого (если есть DTD-описания, то - их разбор);
  • Найдено начало документа (его корневой, самый первый элемент) - вызвать виртуальную функцию- обработчик события startDocument;
  • Каждый раз, когда при разборе будет найден открывающий тэг элемента вызывается обработчик-функция startElement. В качестве параметров ей передаются название элемента и список его атрибутов;
  • Найдено содержимое элемента - передать его соответствующему обработчику - characters, ignorableWhitespace,processingInstruction и т.д.;
  • Если внутри текущего элемента есть под элементы, то эта процедура повторяется;
  • Найден закрывающий тэг элемента - обработать событие endElement();
  • Найден закрывающий тэг корневого элемента -обработать событие endDocument;
  • Если в процессе обработки были обнаружены ошибки, то анализатором вызываются обработчики предупреждений (warning), ошибок (error) и критических ошибок обработчика (fatalError).

Ссылка на объект класса обработчика событий может передаваться объекту XML-анализатора при помощи следующих функций:


- parser.setDocumentHandler(event_class); // - обработчик событий документа
- parser.setEntityResolver(event_class); // - обработчик событий загрузки DTD-описаний
- parser.setDTDHandler(event_class); // - обработчик событий при анализе DTD-описаний
- parser.setErrorHandler(event_class); // - обработчик чрезвычайных ситуаций
Здесь event_class - объект созданного нами ранее класса.

Объект DocumentHandler


- startDocument() // - Начало документа
- endDocument() // - Конец документа
- startElement (String name, AttributeList atts) // - Начало элемента. Функции передается название элемента(открывающий тэг) и список его атрибутов.
- endElement (String name)	 // - Конец элемента
- characters (char[] cbuf, int start, int len) // - Обработка массива текстовых символов
- ignorableWhitespace (char[] cbuf, int start, int len) // - Не обрабатываемые символы
- processingInstruction (String target, String data) // - Обработка инструкций XML-анализатора)

Объект ErrorHandler


- warning (SAXParseException e) // - Получение сообщения о "несерьезной" ошибке. Подробная информация содержится в передаваемом объекте класса SAXParseException
- error (SAXParseException e) // - Сообщение об ошибке
- fatalError (SAXParseException e) // - Сообщение о критической ошибке

Пример:


import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import org.xml.sax.Parser;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.AttributeList;
import org.xml.sax.HandlerBase;
import org.xml.sax.helpers.ParserFactory;
class saxParser extends HandlerBase {
	private PrintWriter out;
	private int elements;
	private int attributes;
	private int characters;
	private int ignorableWhitespace;
	private String url;
	public saxParser(String url_str) {
		url = url_str;
		try {
			out = new PrintWriter(new OutputStreamWriter(System.out, "koi8-r"));
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException(e); // нет вывода - нет работы!
		}
	}
	// =======================================================
	// Обработчики событий. Методы интерфейса DocumentHandler
	// ========================
	// Начало документа
	public void startDocument() {
    // Статистика
        elements            = 0;
        attributes          = 0;
        characters          = 0;
        ignorableWhitespace = 0;
    // Процессорные инструкции 
        out.println("");
    }
	// Конец документа
	public void endDocument() {
		out.flush();
	}
	// Встретился открывающий тэг элемента //
	public void startElement(String name, AttributeList attrs) {
		elements++;
		if (attrs != null) {
			attributes += attrs.getLength();
		}
		// Печать тэга элемента вместе со списком его атрибутов,
		// например, 
		out.print('<');
		out.print(name);
		if (attrs != null) {
			int len = attrs.getLength();
			for (int i = 0; i < len; i++) {
				out.print(' ');
				out.print(attrs.getName(i));
				out.print("=\"");
				out.print(attrs.getValue(i));
				out.print('"');
			}
		}
		out.println('>');
	}
	// Встретился закрывающий тэг элемента
	public void endElement(String name) {
		out.println("");
	}
	// Текстовые символы
	public void characters(char ch[], int start, int length) {
		characters += length;
		out.println(new String(ch, start, length));
	}
	// Не обрабатываемые символы(например, содержимое секции CDATA)
	public void ignorableWhitespace(char ch[], int start, int length) {
		characters(ch, start, length);
	}
	// Инструкции XML-процессору
	public void processingInstruction(String target, String data) {
		out.print(" 0) {
			out.print(' ');
			out.print(data);
		}
		out.print("?>");
	}
	// ===================================================
	// Методы интерфейса ErrorHandler
	// ===============================
	// Последнее предупреждение
	public void warning(SAXParseException ex) {
		System.err.println("Warning at " + ex.getLineNumber() + " . " + ex.getColumnNumber() + "  -  "
				+ ex.getMessage());
	}
	// Произошла ошибка
	public void error(SAXParseException ex) {
		System.err.println("Error at {" + ex.getLineNumber() + "." + ex.getColumnNumber() + "  -  " + ex.getMessage());
	}
	// Такие ошибки исправить уже нельзя
	public void fatalError(SAXParseException ex) throws SAXException {
		System.err.println("Fatal error at {" + ex.getLineNumber() + " . " + ex.getColumnNumber() + "  -  "
				+ ex.getMessage());
		throw ex;
	}
	// =======================================================
	// Вывести информацию о документе
	// ===============================
	public void printInfo() {
		System.out.println();
		System.out.println("Документ " + url + " был успешно обработан");
		System.out.println("Элементов : " + elements);
		System.out.println("Атрибутов : " + attributes);
		System.out.println("Символов  : " + characters);
	}
}
// =======================================================
// Обработка XML документа
// ========================
public class saxSample {
	public static void main(String argv[]) {
		try {
			saxParser sample = new saxParser(argv[0]);
			// так не правельно 
			// Parser parser = ParserFactory.makeParser("com.ibm.xml.parsers.SAXParser");
			// parser.setDocumentHandler(sample);
			// parser.setErrorHandler(sample);
			// parser.parse(argv[0]);
			
			SAXParserFactory factory = SAXParserFactory.newInstance();
			SAXParser saxParser = factory.newSAXParser();
			saxParser.parse(argv[0], sample); 
			sample.printInfo();
		} catch (Exception e) {
			e.printStackTrace(System.err);
		}
	}
}

В выборе способа нужно пользоваться здравым смыслом и поставленными целями.

Послесловие

JAXP (The Java API for XML Processing) — набор абстрактных API, упрощающих обработку XML данных с помощью программ, написанных на JAVA. (подробнее ru.wikipedia.org/wiki/JAXP)

XSLT (eXtensible Stylesheet Language Transformations) — язык преобразования XML-документов. Спецификация XSLT входит в состав XSL и является рекомендацией W3C. (про W3C говорилось в DOM)

Подробнее ru.wikipedia.org/wiki/XSLT
в примерах citforum.ru/internet/xmlxslt/xmlxslt.shtml
в примерах лучше, но на английском http://www.w3.org/TR/xslt)

Использование XSLT в JAXP (трансформация документа)


TransformerFactory tFactory = TransformerFactory.newInstance();
String stylesheet = "prices.xsl";
String sourceId = "newXML.xml";
File pricesHTML = new File("pricesHTML.html");
FileOutputStream os = new FileOutputStream(pricesHTML);
Transformer transformer = tFactory.newTransformer(new StreamSource(stylesheet));  
transformer.transform(new StreamSource(sourceId), new StreamResult(os)); 

Если Вам понравилась статья, проголосуйте за нее

Голосов: 20  loading...
ingwarsmith   zpytnjv   Vanyok   desa551   dimon_lvov   SkunS   pavel_gomel   Alex_Shmalex   davakin111   tovie_rise   karasu   acdc   Yura_Rudakevych   Morrigan   IronVan   NIkaStark   vitaliy24161   frest0512   pelik2005   Nashev