На главную

Учебники
HTML
Dynamic HTML
CSS
CGI
Java
Perl
JavaScript
VBScript
XML
Графика


DOM совместимые анализаторы

   Другим способом представления внутренней структуры документа являются DOM - интерфейсы. Как уже упоминалось, их реализацией занимаются разработчики XML-анализатора, используя для этого возможности конкретного языка программирования. Программисты на Java могут найти эти классы в библиотеке org.w3.dom. Наследуя виртуальные методы DOM интерфейсов, классы анализатора предоставляют приложению стандартный способ манипулирования структурой документа. В свою очередь, приложение, использующее XML-анализатор, может не знать о способе реализации интерфейсов, ему доступна готовая библиотека методов, при помощи которой он может производить поиск нужных фрагментов документа, создавать, удалять и модифицировать его элементы.

   Одним из доступных на сегодня DOM-совместимых наборов классов для работы с документами является библиотека com.ibm.dom, входящая в состав XML анализатора xml4j от IBM. Получить ее можно по адресу www.alphaworks.ibm.com. Принцип использования DOM интерфесов по сравнению с IE5 практически не изменился - поменялись только названия объектов и методов. Их краткий обзор представлен в следующей таблице.

   

Node

Базовый интерфейс для остальных элементов объектной модели XML, представляющий узел дерева структуры документа.

Document

Используется для получения информации о документе и изменения его структуры. Это интерфейс представляет собой корневой элемент XML документа и содержит методы доступа ко всему содержимому документа. При помощи методов объекта Document в программе можно создавать дочерние объекты, представляющие различные конструкции документа (например, createElement - создание элемента, createComment - создание комментария, createTextNode - текстового фрагмента), удалять, перемещать, добавлять объекты (removeChild, replaceChild, insertBefore, ...), перемещаться по дереву элементов(getFirstChild, getLastChild, getNextSibling, getParentNode, getPreviousSibling, ...), получать элементы по их названию (getElementsByTagName, :) и т.д. В объектной модели IE5 этот интерфейс доступен для сценариев на JScript, VB через объект XMLDOMDocument

Element

Представляет элемент документа, определяя методы доступа к его названию(getTagName, getElementsByTagName), атрибутам (getAttribute, getAttributeNode, setAttribute, removeAttribute, : ) и дочерним элементам(appendChild, getChildNodes, getFirstChild, ...).

Attr

Интерфейс, представляющий атрибут элемента. Имеет методы для получения(getValue) и установления(setValue) значения атрибута. Хотя согласно синтаксису XML атрибуты должны назначаться только элементам, в DOM возможно их создание любым объектом, наследующим интерфейс Node. Поэтому можно создать атрибут для документа, который будет находится в списке атрибутов, но не принадлежать ни одному из его элементов.

CharacterData

Интерфейс, предоставляющий доступ к текстовым данным документа. В XML документе к этому типу данных относятся комментарии, текстовое содержимое элементов, секции CDATA. При помощи методов этого интерфейса можно добавлять, удалять, редактировать данные(appendData, deleteData, replaceData, setData), получать размер области текста (getLength) и извлекать текстовое содержимое(getData, substringData, ...)

Comments

Интерфейс для доступа к тексту комментариев

Text

Представляет текстовое содержимое элемента

CDATASection

Интерфейс, представляющий секции CDATA - фрагментов документа, заключенные в символы "[[" и "]]>", которые не обрабатываются XML-анализатором и поэтому могут содержать символы, "запрешенные" в спецификации XML. В эту область можно, к примеру, помещать стилевые таблицы или JavaScript сценарии, используемые при отображении HTML страницы.

ProcessingInstruction

Предоставляет доступ к т.н. области "инструкций процессора", данные из которой используются XML-анализатором при разборе документа. Доступ к этим данным возможен при помощи методо getData, setData и getTarget

Notation

Определяет инструкцию DTD описания. Для получения ее идентификаторов используются методы getPublicId и getSystemId . DOM Level 1 не поддерживает прямого доступа к DTD декларациям по записи и сейчас они доступны лишь для чтения (при помощи параметра nodeName интерфейса Node)

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

/*Пример использования DOM анализатора.Демонстрируется возможность рекурсивного обхода дерева элементов,создание новых элементов, фильтрация элементов (поиска по параметрам)*/import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.io.UnsupportedEncodingException;import java.util.*;import org.w3c.dom.*;import org.xml.sax.Parser;import org.xml.sax.SAXException;import org.xml.sax.helpers.ParserFactory;import com.ibm.xml.parsers.DOMParser;public class logParser {    static String defaultParser =	 "com.ibm.xml.parsers.DOMParser";    static String urlLog;    static  Document xmldoc = null;    static  PrintWriter out;/* Конструктор нашего класса- обработчика. В нем создается выходной поток для печати */     public logParser(String url){     urlLog = url;       try {            out = new PrintWriter			(new OutputStreamWriter(System.out,			 "koi8-r"));        }        catch (UnsupportedEncodingException e) {         System.err.println(e.toString());        }    }    public void parseDoc(){     parseDoc(defaultParser);    }/* Создание класса анализатора, обрабтка им XML-документа и создание объектной модели документа*/    public void parseDoc(String parserName){              try {            Parser parser =		ParserFactory.makeParser(parserName);	    parser.parse(urlLog);// Получение указателя на корневой элемент документа            xmldoc = ((DOMParser)parser).getDocument();        }        catch (Exception e) {         System.err.println(e.toString());                  }       }//=================================================// Вывод содержимого документа в виде форматированного списка XML- элементов //========================                                    public void viewLogAsXML(){        try {	     viewLogAsXML(xmldoc,"");          }        catch (Exception e) {         System.out.println(e.toString());                  }         out.flush();    }/* Рекурсивный обход элементов документа, начиная с указанногоэлемента node.*/    public void viewLogAsXML(Node node,String offs){        if (node == null) {            return;        }        int type = node.getNodeType(); //		 Получение информации о типе текущего узла        switch (type) {/* Если текщий узел - корневой элемент документа */            case Node.DOCUMENT_NODE: {                out.println("<?xml				 version=\"1.0\"				 encoding=\"koi-8\"?>");                viewLogAsXML(((Document)node).				getDocumentElement(),offs);                out.flush();                break;            }/* Если текщий узел - элемент */            case Node.ELEMENT_NODE: {                out.print(offs+"<");// Печать названия элемента                 out.print(node.getNodeName());// Получение списка атрибутов текущего элемента                NamedNodeMap attrs = node.getAttributes();		Node attr;                for (int i = 0; i <				 attrs.getLength(); i++) {                    attr = attrs.item(i);                    out.print(' ');                    out.print(attr.getNodeName()+"=\""+attr.getNodeValue()+"\"");                }                out.println('>');// Получение списка дочерних элементов                NodeList children = node.getChildNodes(); // Если у текщего элемента есть дочерние, то выводим и их                if (children != null) {                    int len = children.getLength();                    for (int i = 0; i < len; i++) {                        viewLogAsXML(children.item(i),						offs+" ");                    }                }                break;            }   /* Если текщий узел - текстовый */            case Node.TEXT_NODE: {                out.println(offs+node.getNodeValue());                break;            }            }// Печать закрывающего тэга элемента        if (type == Node.ELEMENT_NODE) {            out.print(offs+"</");            out.print(node.getNodeName());            out.println('>');        }                          }               //===============================================// Вывод в формате HTML//===================== /* Вызов рекурсивного обходчика */    public void viewLog(){// Header        viewAsHTML("All log records:");        try {// Вывод содержимого	     viewLog(null);        }        catch (Exception e) {         System.out.println(e.toString());                  }// Header        viewAsHTML();    }/* Печать только сообщений об ошибках */    public void viewErrors(){// Header        viewAsHTML("Log errors:");        try {// Вывод содержимого	     viewLog("error");        }        catch (Exception e) {         System.out.println(e.toString());                  }// Footer        viewAsHTML();    }/* Рекурсивный обход элементов, у которых атрибут type равен заданному. */                                                                     public int viewLog(String type){                int i=0;        int elemNum=0;        int messageCount=0;	Element elem;	NodeList elements;	elements = xmldoc.getElementsByTagName	("event");        if(elements==null) System.out.println		("Empty element collection");        elemNum = elements.getLength();        if (type == null) {            for (i = 0; i < elemNum; i++) {	        if(elements.item(i)==null) 			System.out.println			("Empty element");              viewLogMessage((Element)elements.item(i));            }            messageCount=elemNum;        }        else {            for (i = 0; i < elemNum; i++) {                elem = (Element)elements.item(i);                if(elem.getAttribute				("type")==type){                 messageCount++;                 viewLogMessage(elem);                }            }        }       return messageCount;    }/* Печать заголовка таблицы */    public void viewAsHTML(String title){        out.println("<html>");        out.println("<head><title>		Log parser		 sample</title></head>");        out.println("<body><br><b>"+title+"</b><hr>");        out.println("<table cellspacing=\"2\" cellpadding=\"2\" border=\"1\" width=\"600\">");        out.println("<tr bgcolor=\"silver\"><th>IP</th><th>Date</th><th>Method</th><th>Request</th><th>Response</th></tr>");    }/* Печать комментариев к таблице */    public void viewAsHTML(){        Date d = new Date();        String date = new String(""+d.getHours()+":"+d.getMinutes()+":"+d.getSeconds());        out.println("</table><hr>		generated by logParser at <i>"+date+"</i><br></body></html>");        out.flush();    }/* Форматированный вывод содержимого элемента event */    public void viewLogMessage(Element elem){      /* 	 Получение текста внутри элемента - обращаемся к первому	 дочернему узлу (им должен оказаться текст) и получаем его	 значение, используя метод  getNodeValue() интерфейса Node       */      String str_from=(elem.getElementsByTagName("ip-from")).item(0)    .getFirstChild().getNodeValue();      String str_method=(elem.getElementsByTagName("method")).item(0).     getFirstChild().getNodeValue();      String str_to=(elem.getElementsByTagName("url-to")).item(0).getFirstChild().getNodeValue();      String str_result=(elem.getElementsByTagName("response")).item(0).getFirstChild().getNodeValue();      out.println("<tr><td>"+str_from+"</td><td>"+elem.getAttribute("date")+"</td><td>"+str_method+"</td><td>"+str_to+"</td><td>"+str_result+"</td></tr>");    }                             //=======================================================// Модификация дерева элементов//=============================public void logMessage(String result, String datetime,	 String method, String ipfrom, String urlto, 	 String response){      if(xmldoc==null) return;      Element root = xmldoc.getDocumentElement();      Element log_elem = xmldoc.createElement	  ("event");      log_elem.setAttribute("result",result);      log_elem.setAttribute("date",datetime);      Element elem;      Text elem_value;      elem = xmldoc.createElement("method");      elem_value = xmldoc.createTextNode(method);      elem.appendChild(elem_value);      log_elem.appendChild(elem);      elem = xmldoc.createElement("ip-from");      elem_value = xmldoc.createTextNode(ipfrom);      elem.appendChild(elem_value);      log_elem.appendChild(elem);      elem = xmldoc.createElement("url-to");      elem_value = xmldoc.createTextNode(urlto);      elem.appendChild(elem_value);      log_elem.appendChild(elem);      elem = xmldoc.createElement("response");      elem_value = xmldoc.createTextNode(response);      elem.appendChild(elem_value);      log_elem.appendChild(elem);      root.appendChild(log_elem);     }//================================================// Пример использования методов класса logParser//==============================================    public static void main(String argv[]) {/* Создание объекта анализатора. В качестве параметра ему  передается название документа(можно и через  командную строку, конечно...)*/ logParser log_file = new logParser("log.xml");    log_file.parseDoc();              // Анализ документа   if (argv.length == 0) {         // Что с ним делать      log_file.viewLogAsXML();		    System.exit(0);        }                             for (int i = 0; i < argv.length; i++) {            String arg = argv[i];            if (arg.startsWith("-")) {                if (arg.equals("-vx")) {                    log_file.viewLogAsXML();                    break;                }                if (arg.equals("-va")) {                    log_file.viewLog();                    break;                }                if (arg.equals("-ve")) {                    log_file.viewErrors();                    break;                }	        if (arg.equals("-h")) {        	   usage();                }            }        }      log_file.logMessage("success","12","GET","127.0.0.1","./index.html","200");      log_file.viewLogAsXML();    }    private static void usage() {        System.err.println("usage: 		java logParser (options)");        System.err.println();        System.err.println("options:");        System.err.println("  	-vx View result as XML tree (default)");        System.err.println("  	-va View all messages as HTML page");        System.err.println(" 	 -ve View only errors as HTML page");        System.err.println(" 	 -h  View help ");    } }

   Комментарии

   Более подробные комментарии, файлы приложений и результатов их работы можно найти по адресу www.mrcpk.nstu.ru/xml/

Назад