Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> как проверить заголовок XML? 
V
    Опции темы
stan90
Дата 28.11.2009, 17:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 12.11.2009

Репутация: нет
Всего: нет



у меня есть синтаксический анализатор XML файла,но у меня получилось сделать только чтобы он проверял открывающиеся и закрывающиеся теги и показывал номер позиции где ошибка...
подскажите пожалуйста как сделать проверку для заголовка?
Код



import java.io.*;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class XMLParser {
    //Для дальнейшего анализа ошибок предусмотрим защищенное поле curPos,
    //которое будет содержать номер символа, на котором остановилось чтение выражения.
    //Соответственно, при вызове метода parse() необходимо обнулить это поле.
protected int curPos = 0;
protected BufferedReader inputText;
protected Stack<XMLTag> stack = new Stack<XMLTag>();
private String errorMessage;
private Object oldCurrPos;
public boolean parse(BufferedReader inputText) throws IOException {
    //является единственным публичным методом, 
    //т.е. на данный момент представляет интерфейс класса. 
    //На вход ему пользователь должен передать объект класса потокового ввода текстовых данных 
    //с буферизацией BufferedReader, который записывается в защищенное поле inputText
this.inputText = inputText;
curPos = 0;
boolean result = parseHeader();
//метод parse() передает управление методу parseHeader() 
//для анализа заголовка выражения
return result ? parseTag() : false;
}
/*protected Boolean parseNameTag(String tag)
{
  if (tag.equals(""))
    return Boolean.valueOf(true);
  Pattern pattern = 
    Pattern.compile("[a-zA-Z\\u005F]{1}[a-zA-Z\\d\\u002D\\u002E\\u005F]*");
  Matcher matcher = pattern.matcher(tag);
  if (matcher.matches())
    return Boolean.valueOf(true);

  this.errorMessage = "Неправильное имя идентификатора";
  this.curPos = Integer.valueOf(((Integer) this.oldCurrPos).intValue() + 1);
  return Boolean.valueOf(false);
}*/


protected boolean parseHeader() {
return true;
}

protected boolean parseTag() throws IOException {
skipWS(); // пропустим пробельные символы
boolean result = parseOTag(); // первым должен идти открывающий тег
if (!result) // если результат отрицательный
return false; // возвращаем ложь
do { // в цикле
skipToDelimeters("<"); // пропускаем все символы до левой угловой
// скобки. Этом может быть полезный текст -
// в будущем будем его использоват
if (testStart("</")) // проверим, не закрывающий ли это тег
return parseCTag(); // и если да, то вернем результат его
// анализа — завершаем обработку данного
// тега
if (testStart("<")) { // если это был не закрывающий тег, проверим,
// не похоже ли это на вложенный открывающий
// тег
if (!parseTag()) // и проанализиуем его (рекурсивный вызов), но
// если результат отрицательный,
return false; // вернем ложь
} else
// а если это был не закрывающий и не открывающий тег, то мы
// дошли до конца потока ввода
return false; // в этом случае возвращаем ложь
} while (true); // цикл не имеет условия выхода — возврат осуществляется
// из тела цикла
}

protected boolean parseOTag() throws IOException {
skipWS();
if (!testStart("<"))
        return false;
    if (testStart("</"))
        return false;
int c = inputText.read();
    curPos++;
XMLTag tag = new XMLTag(skipToDelimeters("> \n\t"));
    stack.push(tag);
    if (!testStart(">"))
        if (!parseParams(tag))
            return false;
c = inputText.read();
    if (c != 13)
        curPos++;
    if (c == '>')
        return true;
    else
        return false;
}

protected boolean parseParams(XMLTag tag) throws IOException {
    //Прежде чем модифицировать метод обработки открывающего тега 
    //напишем «заглушку» вспомогательного метода,
    //обрабатывающего параметры тега
    skipToDelimeters(">");
    return true;
}

protected boolean parseCTag() throws IOException {
    skipWS();
    if (!testStart("</"))
        return false;
    inputText.skip(2);
    curPos+=2;
    XMLTag tag = stack.pop();
    if (!tag.name.equals(skipToDelimeters(">")))
        return false;
    int c = inputText.read();
    if (c != 13)
        curPos++;
    if (c == '>')
        return true;
    else
        return false;
}


public boolean testStart(String str) throws IOException {
    //Метод testStart() принимает на входе строку и проверяет, 
    //совпадает ли она с началом выражения считая с текущей позиции
int len = str.length(); // запишем длину переданной на входе строки в
// переменную len
char[] cbuf = new char[len]; // создадим массив символов длины len
inputText.mark(len); // «Отметим» место в потоке ввода (в выражении).
// Метод reset() позволит к нему вернуться, если
// мы считаем не более, чем len символов
len = inputText.read(cbuf, 0, len); // прочитаем в массив cbuf с текущей
// (нулевой) позиции len символов и
// запишем в len количество
// фактически прочитанных символов
inputText.reset(); // вернем поток ввода в исходное состояние
if (len == -1) // если ничего не удалось прочитать, вернем ложь
return false;
String sbuf = new String(cbuf, 0, len); // на основе массива cbuf
// создадим строку (из его
// первых len символов)
if (sbuf.compareToIgnoreCase(str) == 0) // если строка на входе равна
// строке sbuf, вернем истину
return true;
else
// иначе, вернем ложь
return false;
}

protected void skipWS() throws IOException {
    //Метод skipWS() пропускает все идущие подряд пробельные символы в выражении 
    //с текущей позиции
int c; // локальная переменная для последовательного чтения символов
do {
inputText.mark(1); // отметим положение в потоке ввода, чтобы иметь
// возможность вернуться на 1 символ
c = inputText.read(); // прочитаем символ из потока
if (c != 13) // увеличим счетчик количества считанных символов. При
// переводе строки в Windows генерируется два
// символа с кодами 13 (0xD, возврат каретки) и 10
// (0xA, перевод строки), в Linux — только 10 (0xA).
// Т.е. условие введено для корректного подсчета
// символов перевода строки в Windows, при
// сохранении совместимости с Linux
curPos++;
} while (Character.isWhitespace(c)); // продолжим, пока встречаются
// пробельные символы. Для того,
// чтобы определить что
// прочитанный символ является
// пробельным, воспользуемся
// статическим методом
// isWihtespace() класса
// Character.
inputText.reset(); // вернем поток в исходное состояние (на 1 символ
// назад), т.к. последний символ не был пробельным
curPos--; // и исключим этот символ из счетчика
}

protected String skipToDelimeters(String delimeters) throws IOException {
    //Метод skipToDelimeters() считывает все символы в выражении с текущей позиции, 
    //пока не встретит один из символов, перечисленных в строке delimeters
int c; // локальная переменная для последовательного чтения символов
StringBuffer sb = new StringBuffer(); // буфер для хранения
// последовательности считанных
// символов
do { // в цикле
inputText.mark(1);// отметим положение в потоке ввода, чтобы иметь
// возможность вернуться на 1 символ
c = inputText.read(); // прочитаем символ из потока
if (delimeters.indexOf(c) == -1 && c != -1) { // если символ с не
// встречается в
// строке delimeters
// и при этом он был
// успешно прочитан
// (c != -1),
sb.append((char) c); // то добавляем его в буфер sb
if (c != 13)
curPos++; // и увеличиваем счетчик прочитанных символов (по
// условию (c != 13) см. метод skipWS())
} else
break; // иначе выйдем из цикла
} while (true);
inputText.reset(); // последний символ присутствовал в строке
// delimeters, возвратим поток в исходное положение
return sb.toString().trim(); // вернем в качестве результата считанные в
// буфер sb символы, преобразовав его к
// стоке и обрезав с обеих сторон
// пробельные символы
}

public int getCurPos() {
    //Метод getCurPos() расширяет интерфейс класса XMLParser,
    //позволяя пользователю узнать положение в потоке ввода (после вызова метода parse()).
return curPos;
}


public static void main(String[] args) throws IOException {
BufferedReader isr = new BufferedReader(new InputStreamReader(//Объект isr класса BufferedReader 
//создается для чтения из файла test.txt
// (System.in));
new FileInputStream("test.txt"), "cp1251"));
XMLParser xp = new XMLParser();//Далее создается объект класса XMLParser 
//и на экран выводятся результат анализа текста 
//(true/false, т.е. успешно/неуспешно) и порядковый номер символа, 
//на котором остановилась обработка.
System.out.println(xp.parse(isr));
System.out.println(xp.curPos);
}
}

PM MAIL   Вверх
LSD
Дата 29.11.2009, 12:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



А зачем писать свой велосипед? Почему бы не использовать стандартный SAX парсер?


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
stan90
Дата 29.11.2009, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 12.11.2009

Репутация: нет
Всего: нет



у меня задание такое))
PM MAIL   Вверх
stan90
Дата 30.11.2009, 18:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 12.11.2009

Репутация: нет
Всего: нет



товарищи очень нужна ваша помощь!!)
PM MAIL   Вверх
ivanovpv
Дата 30.11.2009, 19:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Варвар
**


Профиль
Группа: Участник
Сообщений: 639
Регистрация: 26.1.2005
Где: Москва

Репутация: 4
Всего: 28



Таких задание-творцов надо фтопку... Проще же применить SAX парсер ловить исключения и выкидывать сообщения парсера...

Если ближе к телу, то парсер проще сделать рекурсивным примерно таким:
1) Распознавание заголовка
2) Чтение первого тега
   а) Если есть вложенный тег - начинаем рекурсию (см. п.1)
3) Чтение закрывающего тега

Отдельно обработки собственно тега (выделение параметров), убирание пробелов, комментариев




--------------------
Aut viam inveniam aut faciam
PM MAIL Skype   Вверх
stan90
Дата 30.11.2009, 22:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 12.11.2009

Репутация: нет
Всего: нет



ну вот я сделал для открывающихся и закрывающихся тегов..а как для комментариев,загаловка и параметров сделать я не знаю..у меня не получается)
PM MAIL   Вверх
rimidal
Дата 1.12.2009, 09:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 25.9.2007

Репутация: 1
Всего: 1



Есть такая штука как БНФ и РБНФ. Это что касается теории парсеров. К этой теории также относятся конечные автоматы и регулярные выражения.

Есть еще генераторы парсеров (еще их называют компиляторы компиляторов). Я например использовал CocoR. Для него есть плагин под eclipse. Но есть и множество других генераторов. Их можно найти например здесь: http://www.java-sources.org/open-source/parser-generators

Это сообщение отредактировал(а) rimidal - 1.12.2009, 10:17
PM MAIL   Вверх
stan90
Дата 1.12.2009, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 12.11.2009

Репутация: нет
Всего: нет



так мне не нужны никакие генераторы))

мне нужно чтобы программа которую я начал писать проверяла правильно ли составлен XML документ или нет)
PM MAIL   Вверх
rimidal
Дата 1.12.2009, 23:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 25.9.2007

Репутация: 1
Всего: 1



Цитата

так мне не нужны никакие генераторы))

мне нужно чтобы программа которую я начал писать проверяла правильно ли составлен XML документ или нет)


Генератор сгенерирует вам исходный код тех классов которые и должны выполнять эту задачу.
На примере CocoR :
1. Надо описать парсер на БНФ (в вашем случае это БНФ XML-я - его кстати можно найти в интернете).
2. По полученому БНФ будут сгенерированы исходники двух классов которые после компиляции будут производить разбор выражений (в вашем случае XML файлы).

Правда здесь есть один момент - надо знать синтаксис описания БНФ для конкретного генератора. Как правило к генераторам прилагаются примеры - может и повезет с XML-ем.
PM MAIL   Вверх
LSD
Дата 2.12.2009, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Заголовок XML, это processing instruction и в принципе она может встречаться в любом месте XML документа (вернее заголовок может быть, только в начале, а вот другие processing instruction в любом месте).

В твоем случае, тебе надо сделать парсинг помимо тегов, еще и processing instructions, комментариев, DTD, CDATA. Создай отдельный класс, который будет заниматься разбивкой входного текста на теги: открывающий тег, закрывающий тег, тело тега, комментарий, DTD, CDATA и processing instruction.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
rimidal
Дата 2.12.2009, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 25.9.2007

Репутация: 1
Всего: 1



EBNF для XML: 
EBNF for XML 1.0

Ох и не простая эта задача, даже с генератором.
PM MAIL   Вверх
stan90
Дата 3.12.2009, 01:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 12.11.2009

Репутация: нет
Всего: нет



а ни у кого нет  может быть кода какого нить парсера для проверки xml,я бы по анологии разобрался бы?)
PM MAIL   Вверх
rimidal
Дата 3.12.2009, 08:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 51
Регистрация: 25.9.2007

Репутация: 1
Всего: 1



Так ведь SAX открытая библиотека, с исходниками. Можно посмотреть там.

http://sourceforge.net/projects/sax/files/
PM MAIL   Вверх
stan90
Дата 4.12.2009, 08:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 136
Регистрация: 12.11.2009

Репутация: нет
Всего: нет



не то..(
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1370 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.