BufferedReader и перечисление нескольких строк в Java

Я нахожусь в процессе создания Java-приложения, которое читает через .ttl файл строка за строкой и создает graphml файл для представления онтологии.

У меня возникли проблемы с выяснением, как перечислить определенный раздел.

я использую BufferedReader читать каждую строку.

Например, у меня есть следующее:

else if (line.contains("owl:oneOf")){

    // insert code to enumerate list contained in ( )

}

И вот как выглядит.ttl для oneOf:

    owl:oneOf  (GUIFlow:ExactlyOne
                GUIFlow:OneOrMore
                GUIFlow:ZeroOrMore
                GUIFlow:ZeroOrOne ) 

Мне нужно вернуть эти 4 объекта в виде одного списка, чтобы использовать его как часть графического представления онтологии.

2 ответа

Рассматривали ли вы (и отвергли) существующие решения, например: Йена?

Видимо, у вас есть какой-то цикл, проходящий через файл. Вот несколько идей:

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

Vector<String> oneOfList = null;

while(reader.ready()){
    String line=reader.readLine();

    if(line.contains("foo")){
        ...
    }
    else if (line.contains("owl:oneOf")){
        oneOfList = new Vector<String>();
    }

    if(oneOfList!=null){
        String str = line.trim();
        int a = str.indexOf("(");  // -1 if not found, OK
        int b = str.indexOf(")");
        if(b<0) b=str.length();
        oneOfList.add(str.substring(a+1,b).trim());
    }

    if (line.contains(")")){
        storeOneOf(oneOfList);
        oneOfList=null;
    }

}

2) Когда встречается заголовок oneOf, создайте еще один маленький цикл для чтения его значений. Возможный недостаток может заключаться в том, что в результате вы получите два цикла, повторяющихся по файлу, и два вызова reader.readLine, что может усложнить вещи или не может.

while(reader.ready()){
    String line=reader.readLine();

    if(line.contains("foo")){
        ...
    }
    else if (line.contains("owl:oneOf")){
        Vector<String> oneOfList = new Vector<String>();
        while(true){
            String str = line.trim();
            int a = str.indexOf("(");  // -1 if not found, OK
            int b = str.indexOf(")");
            int c = (b>=0) ? b : str.length();
            oneOfList.add(str.substring(a+1,c).trim());
            if(b>=0) break;
            line=reader.readLine();
        }
        storeOneOf(oneOfList);
    }

}

3) Приведенные выше алгоритмы основаны на том, что заголовок, ( и первое значение находится в одной строке и т. д. Если исходный файл отформатирован немного по-другому, синтаксический анализ не удастся. Более гибкий подход может заключаться в использовании StreamTokenizer который автоматически игнорирует пробелы и разделяет текст на слова и отдельные символы:

StreamTokenizer tokzr=new StreamTokenizer(reader);
tokzr.wordChars(':',':');

while( tokzr.nextToken() != tokzr.TT_EOF ){
    if( tokzr.ttype==tokzr.TT_WORD && tokzr.sval.equals("foo") ){
        ...
    }
    else if ( tokzr.ttype==tokzr.TT_WORD && tokzr.sval.equals("owl:oneOf") ){
        if(tokzr.nextToken()!='(') throw new Exception("\"(\" expected");
        Vector<String> oneOfList = new Vector<String>();
        while(tokzr.nextToken() == tokzr.TT_WORD){
            oneOfList.add(tokzr.sval);
        }
        storeOneOf(oneOfList);
        if(tokzr.ttype!=')') throw new Exception("\")\" expected");
    }
}
Другие вопросы по тегам