2016-02-05 45 views
0

我正在製作一個java應用程序,它通過逐行讀取.ttl文件並創建graphml文件來表示本體。BufferedReader並枚舉Java中的多行

我在計算如何枚舉某個節時遇到了一些麻煩。

我使用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個對象作爲一個清單,被用作本體的圖形表示的一部分。

+1

你會根據當前狀態解析行並解釋行內容,也就是說,如果你以前遇到過'owl:oneOf('你知道你有元素'owl:oneOf'和列表的開始,那麼接下來是列表元素,直到遇到相應的')'。 – Thomas

+0

我建議不要從頭開始編寫Turtle解析器。有各種API已經允許解析,其中許多是開源的,所以你可以直接使用它們,或者擴展/重用代碼來適應你的應用程序。芝加哥和耶拿在大衛 - 索羅科的回答中提到,是兩個很好的起點。 – Ignazio

回答

1

顯然你有一些循環通過該文件。這裏有一些想法:

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"); 
    } 
} 
+0

是的,我有一個while循環。我非常喜歡StreamTokenizer的想法,但我一定會嘗試每種方法,看看哪種效果最好。非常感謝您提供如此徹底的答覆! –

1

你有沒有考慮(和拒絕)現有的解決方案e.g:Jena