powered by simpleCommunicator - 2.0.30     © 2024 Programmizd 02
Map
Форумы / Java [игнор отключен] [закрыт для гостей] / Стек, теги XML
25 сообщений из 33, страница 1 из 2
Стек, теги XML
    #39941201
utlikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Задание такое:
.
Написать программу, проверяющую правильно ли в файле XML вложены и закрыты теги с ипользованием стека как вспомогательной системы. Программа проверяет только некоторые теги, их список записан в текстовом файле с синтаксисом, используемом во внешнем представлении объекта класса Properties.
.
txt файл с Properties такой:
count=3
e1=YEAR
e2=PRICE
e3=CD
.
Подскажите в какую сторону двигаться, что можно тут попробовать, потому что не хватает значний языка для реализации такой задачи.
Моя идея такая: создать два стека - левый, в который ложим открывающиеся теги, и правый для закрывающихся, а потом их сравниваем, при не правильно составленном XML документе получим предупреждение типа в таком то месте ошибка.
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941261
utlikk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Предположительный код:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
class ReadProperties {

       public static void main(final String[] args) throws IOException {
        final Properties props = new Properties();
        props.load(new FileReader("test1.txt"));
        System.out.println(props);

        final int count = Integer.parseInt(props.getProperty("count"));
        System.out.println("count=" + count);

        for (int i = 1; i <= count; i++) {
                final String propertyName = "e" + i;
                final String markUp = props.getProperty(propertyName);
                System.out.println("markUp=" + markUp);
        }

        Stack<String> left = new Stack<>();
        Stack<String> right = new Stack<>();
        String s;

        FileReader reader = new FileReader("test1fail.xml");
        while (reader.ready()){
            String data = reader.toString();
        int licz = 0;
        for(int a = 0; a <= data.length()+1 ; a++){

            s = String.valueOf(data.charAt(a));

            switch (s) {
                case "<YEAR>":
                case "<CD>":
                case "<PRICE>":
                    left.push(s);
                    break;
                case "</YEAR>":
                case "</CD>":
                case "</PRICE>":
                    right.push(s);
                    break;
            }

            String l = left.pop();
            String r = right.pop();

            if (l.equals(r)) {
            } else {
                System.out.println("Проблема в " + licz + "ом по счету "+ l);
            }
            licz++;
        }
       }
     reader.close();
    }
}
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941310
Garrick
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
utlikk, что-нибудь про XSD и валидацию XML слышали?
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941342
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
utlikk
Предположительный код:

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
        for(int a = 0; a <= data.length()+1 ; a++){

            s = String.valueOf(data.charAt(a));

            switch (s) {
                case "<YEAR>":
....
            }


Жесть какая.
Понятно, что "предположительный", но все же жесть.

Читать книжки про конечные автоматы и парсеры. Вроде что-то было у Вирта. Хотя книжка Вирта мне не очень понравилась, но других просто не помню.

https://www.ozon.ru/context/detail/id/4803779/

AFAIK
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941343
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
utlikk

Моя идея такая: создать два стека....

Стека явно достаточно одного.
При открытии тэга - push
При закрытии тэга - pop

А текущей элемент вообще в стек класть не нужно

IMHO
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941349
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
utlikk, в этой задаче есть два смысла.

1) Ты изучаешь xml или алгоритмы со стеком и просто играешся. Тогда делай стеками или деками или очередями как хочешь.

2) Ты делаешь продуктовую систему которая должна
- проверить что документ является well-formatted (правильно форматированным). Для этого его можно просто
"перемотать через XMLStreamReader.
- проверить что предыдущий пункт выполнен + еще и документ валиден. Это уже - соответсвие DTD (Document Type
Definition) старое и архаичное или XSD (XML Schema definition). Схему ты должен либо описать сам либо взять готовую.
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941354
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Если кто помнит книжки по построению парсеров и конечных автоматов, стоило бы автору топика ссылок накидать. IMHO. В любом случае пригодится.
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941355
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Все зависит от глубины увлеченности человека. Мне сегодня тема проектирования парсеров
настолько далека что я вообще не могу ее осилить. Просто в силу своего перфекционизма.
Начинаю делать с Antlr/JavaCC и понимаю как глубоко закопался и потом плюю и решаю
все конечным автоматом над потоком символов. Просто задачи обычно тупые попадаются.
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941373
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton

Ну дык в примере кода даже не видна попытка побить на токены. Т.е. прочитать что нибудь про конечные автомы стоило бы (а в книжке Вирт'а AFAIK про конечные автоматы как-то бедно написано)

mayton
потом плюю и решаю все конечным автоматом над потоком символов

AFAIK по общению с бывшими студентами, хорошо, если после обучения вообще такой термин помнят/знают ))) Но про использование данного термина в банальных задачах типа побить входной поток на токены - вместо sql.ru все же лучше почитать книжки.

Выложенный пример кода с конструкцией:
Код: java
1.
2.
3.
        for(int a = 0; a <= data.length()+1 ; a++){

            s = String.valueOf(data.charAt(a));


все же немного жесть ))) даже для "предположительный код"

Что лично мне не нравится:
1) для чтения входного потока совершенно не нужно загонять его в память и максимум достаточно операции readChar
2) для дальнейшей проверки на тэги, входной поток из потока символов нужно превратить в поток токенов/тэгов. Т.е. нужно реализовать этот самый конечный автомат, который readChar превратит в readToken или readXmlTag

IMHO
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941387
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Давай поможем бедняге. Чисто механический рефакторинг. Даже вот глубого не вникая в логику
а просто выбрасывая ненужные действия.
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941397
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
тогда уж вбрасывая нужные
сначала - преобразование входного потока в поток токенов/тэгов
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941405
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Типо того
Код: java
1.
2.
3.
4.
interface TokenStream {
   boolean hasNext();
   String nextToken();
}
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941413
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
utlikk
Написать программу, проверяющую правильно ли в файле XML вложены и закрыты теги с ипользованием стека как вспомогательной системы


Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
MyTokinizer tokinizer = new MyTokinizer( new FileInputStream( fileName ) );
MyToken currentToken = null;
Stack stack = new ....;
while ( tokinizer.hasNext() {
   MyToken  nextToken = tokinizer.readToken();
   if ( nextToken.isOpenTag() ) {
      // Открывающий тэг, текущий просто сохраняем в стеке
      stack.push( currentToken );
      currentToken = nextToken;
   } else if ( nextToken.isCloseTag() ) {
     // или XML начинается с закрывающего тэга - оригинально
     // или закрывающих тэгов больше, что открывающих
     if ( currentToken  == null ) {
        throw new MyTokenMistmathException();
     }
     // Закрывающий тэг должен равняться открывающему
     if ( ! nextToken.getTagName().equal( currentToken.getTagName ) ) {
        throw new MyTokenMistmathException();
     }
     currentToken = stack.pop();
     // EmptyStackException быть не может, т.к. первым элементом
     // мы все равно будет туда класть currentToken=null
  }
}  // while
// Поток закончился, проверяем, что не осталось открытых тэгов
if ( stack.size() != 0 ) {
  throw new MyTokenMistmathException();
}



utlikk
Программа проверяет только некоторые теги

странное условие, если нужно - добавить
зачем проверять только некоторые, когда проще проверить все - не понятно
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941414
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Типо того
Код: java
1.
2.
3.
4.
interface TokenStream {
   boolean hasNext();
   String nextToken();
}


В топку. Тэг в XML имеет значительно более сложную структуру, что String
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941417
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Согласен. Ну так ты за беднягу все сделаешь. Лучше пускай бы он сам реализацию писал.
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941419
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Например токен из входного потока
<PRICE value="100" currency="USD">
явно не String

Как минимум нам нужно знать:
1. Тип токена/тэга:
1.1. Открывающий тэг <PRICE...>
1.2. Закрывающий тэг </PRICE>
1.3. "самодостаточный" тэг <PRICE .../>
1.4. Комеентарии
1.5. Значения между тегами <tag>VALUE</tag> и прочий мусор
возможно что-то еще. По хорошему нужно читать стандарт XML

1.3 - 1.5 для данной задачи в принципе не важны, но для парсера токенов будут различаться (например комментарии! вполне могут содержать < >)

2. Имя тэга, если это тег
Т.е. <PRICE.... и <PRICE..../> и </PRICE => PRICE

Для простоты, я бы хранил:

tokenType -
rawSource - сырые данные, весь входной поток данных включая < и >
tagName - выделенное имя тэга

вычлинять атрибуты в тэгах вряд ли требуется
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941422
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AFAIK В токенайзере самое мутороное будет комментарии выделить.

<!--Your comment-->

одна эта конструкция 8 состояний конечного автомата даст ((( мне кажется больше, чем весь остальной токенайзер )))
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941426
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Согласен. Ну так ты за беднягу все сделаешь. Лучше пускай бы он сам реализацию писал.

То, что почему-то не понимают "студенты желающие помоши"

Если он принесет _нормальный_ токенайз преподавателю, то первый вопрос будет:
что такое конечный автомат?
после чего преподаватель с точностью 99.99% будет знать, что задание списано/заказано
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941427
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Полную спеку сложно поддержать. Вместе с блоками processing instructions и entities.

Лучше забить пока на коментарии и сделать что-то простое и деревянное. А потом по необходимости допилить.
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941429
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Вместе с блоками processing instructions и entities.

+100500

Если есть ссылка на спеку, линкани в тему.

лично я сложности не вижу. с комментариями тоже сложности нет, но больно монстрообразно получится.

Есть еще открытый вопрос: а имя тэга по стандарту может содержать символы < и > ?

кто читал рендеринг срачь в соседней ветке, вопрос должны понять )))


mayton
Лучше забить пока на коментарии

Облом )))
В приложенном топик стартере файле есть комментарии
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941437
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не смотрел его файл.

Надо спросить его.

Афтор. Этот кейс покрывает все-все варианты? Или еще может какой-то синтасис прилететь?
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941439
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я боюсь читать про серверный рендеринг. У меня есть свой взгяд на проблему. Но поскольку я не юайщик
то моё мнение носит сугубо теоретически и рекомендательный характер и вряд-ли будет интересно
тем зубрам которые там бодаются. Пускай себе бодаются вусмерть..

Хотя по части инженерной графики я много чего знаю и могу рассказать.
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941473
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Фигня получилась. Нужно спецификация по XML читать.

Отделяет тэги от не тэгов, за тот же проход выделяет имя токена
Отделение OPEN_TAG от CLOSE_TAG не сделано, пусть автор читает книжки и дорабатывает )))

Осталось добавить состояния парсера для выделения символа '/' перед именем токена и можно двигаться дальше )))

Почему фигня, т.к. в атрибутах тэга вполне могут встретиться символы / < > Текущий вариант лично меня бы не устроил. Но, возможно, для "студента" и пойдет.

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringReader;

enum MyXmlTokenType {  TT_UNKNOWN_TAG, TT_OPEN_TAG, TT_CLOSE_TAG, TT_ONE_TAG, TT_OTHERS }

class MyXmlToken {
     MyXmlTokenType tokenType;
     StringBuilder rawSource;
     StringBuilder tokenName;
     public MyXmlToken() {
         tokenType = MyXmlTokenType.TT_OTHERS;
         rawSource = new StringBuilder();
         tokenName = new StringBuilder();
     }
}

enum TokenizerState { ST_START, ST_TAG_OPENED, ST_TAG_NAME, ST_TAG_AFTER_NAME, ST_OTHER_TEXT }

class MyTokenizer {
    boolean isEof;
    Reader inp;
    int char_to_return;

    public MyTokenizer(Reader reader) {
        inp = reader;
        char_to_return = -1;
        isEof = false;
    }
    boolean hasNext() {
        return ! isEof;
    }
    MyXmlToken readNextToken() throws IOException {
        TokenizerState currentState = TokenizerState.ST_START;
        MyXmlToken token = new MyXmlToken();
        int c = -1, prev_char = -1;
        while ( true ) {
            // Запоминаем предыдущий символ, это как-то не совсем в духе
            // конечного автомата, но пофиг
            prev_char = c;
            // Чтение одного символа из входного потока
            // символ мог остаться недообработанным от пред. вызова
            if ( char_to_return > 0 ) {
               c = char_to_return;
               char_to_return = -1;
             } else {
               c = inp.read();
               if ( c <  0 ) {
                  isEof = true;
                  return token;
               }
            }
            switch ( currentState ) {
                // Начало потока, может быть символ < или любые другие
                case ST_START:
                    token.rawSource.append( (char)c );
                    if ( c=='<' ) {
                        currentState = TokenizerState.ST_TAG_OPENED;
                        token.tokenType = MyXmlTokenType.TT_UNKNOWN_TAG;
                    } else {
                        currentState = TokenizerState.ST_OTHER_TEXT;
                        token.tokenType = MyXmlTokenType.TT_OTHERS;
                    }
                    break;
                case ST_TAG_OPENED:
                    token.rawSource.append( (char)c );
                    if ( c=='>' ) {
                        return token;
                    } else {
                        currentState = TokenizerState.ST_TAG_NAME;
                        token.tokenName.append( (char)c );
                    }
                    break;
                case ST_TAG_NAME:
                    token.rawSource.append( (char)c );
                    if ( c=='>' ) {
                        return token;
                    }
                    else if ( c==' ' || c=='/' ) {   // Кроме пробелов могут быть и другие пробельные символы
                        currentState = TokenizerState.ST_TAG_AFTER_NAME;
                    }
                    else {
                        token.tokenName.append( (char)c );
                    }
                    break;
                case ST_TAG_AFTER_NAME:
                    token.rawSource.append( (char)c );
                    if ( c=='>' ) {
                        if ( prev_char=='/' ) {
                            token.tokenType=MyXmlTokenType.TT_ONE_TAG;
                        }
                        return token;
                    }
                    break;
                case ST_OTHER_TEXT:
                    if ( c=='<' ) {
                        this.char_to_return = c;
                        return token;
                    }
                    token.rawSource.append( (char)c );
                    break;
            }
        }
    }
}

public class Tokenizer1 {
    public static void main(String[] args) throws Exception {
        MyTokenizer tokenizer = new MyTokenizer( new StringReader( "<PRICE>100</PRICE><ONE/><ONE some text/><TAG attr=\"attr\">value</TAG>"));
        while ( tokenizer.hasNext() ) {
            MyXmlToken token = tokenizer.readNextToken();
            System.out.println( token.tokenType.toString()+" "+token.tokenName+" "+token.rawSource);
        }
    }
}

...
Рейтинг: 0 / 0
Стек, теги XML
    #39941481
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Можно ускорить этот парсер.
...
Рейтинг: 0 / 0
Стек, теги XML
    #39941491
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Можно ускорить этот парсер.

Чего там ускорять то?
некая избыточность c rawSource есть, но как-то хочется возможности по уже распарсенному документу имееть возможно оригинал возстановить.
...
Рейтинг: 0 / 0
25 сообщений из 33, страница 1 из 2
Форумы / Java [игнор отключен] [закрыт для гостей] / Стек, теги XML
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]