BufferedReader和Java中的多行枚举
我正在制作一个java应用程序,它逐行读取BufferedReader和Java中的多行枚举,java,bufferedreader,enumeration,owl,ontology,Java,Bufferedreader,Enumeration,Owl,Ontology,我正在制作一个java应用程序,它逐行读取.ttl文件,并创建一个graphml文件来表示本体 我在计算如何列举某一部分时遇到了一些困难 我正在使用BufferedReader阅读每一行 例如,我有以下几点: else if (line.contains("owl:oneOf")){ // insert code to enumerate list contained in ( ) } 这就是其中一个.ttl的外观: owl:oneOf (GUIFlow:ExactlyO
.ttl
文件,并创建一个graphml
文件来表示本体
我在计算如何列举某一部分时遇到了一些困难
我正在使用BufferedReader
阅读每一行
例如,我有以下几点:
else if (line.contains("owl:oneOf")){
// insert code to enumerate list contained in ( )
}
这就是其中一个.ttl的外观:
owl:oneOf (GUIFlow:ExactlyOne
GUIFlow:OneOrMore
GUIFlow:ZeroOrMore
GUIFlow:ZeroOrOne )
我需要将这4个对象作为一个列表返回,作为本体图形表示的一部分使用。显然,文件中有某种循环。以下是一些想法: 1)在循环中引入一个“状态”,这样在阅读下一行时,它就会知道它实际上在列表中。存储列表的动态数组可以用作状态。遇到
(
)时创建列表,遇到时将列表发送到需要的任何位置。
,然后删除该列表。一个复杂的情况是,根据源格式,您必须在向列表添加值之前创建列表,并在添加值之后处理和删除列表,因为(
和)
与实际值位于同一行
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;
}
}
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");
}
}
StreamTokenizer tokzr=新的StreamTokenizer(读卡器);
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()!='(')抛出新异常(“\”(\”预期”);
Vector oneOfList=新向量();
while(tokzr.nextToken()=tokzr.TT_单词){
添加(tokzr.sval);
}
storeOneOf(列表中的一个);
if(tokzr.ttype!='))抛出新异常(“预期”);
}
}
显然,您在文件中有某种循环。以下是一些想法:
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;
}
}
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");
}
}
StreamTokenizer tokzr=新的StreamTokenizer(读卡器);
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()!='(')抛出新异常(“\”(\”预期”);
Vector oneOfList=新向量();
while(tokzr.nextToken()=tokzr.TT_单词){
添加(tokzr.sval);
}
storeOneOf(列表中的一个);
if(tokzr.ttype!='))抛出新异常(“预期”);
}
}
您是否考虑(并拒绝)现有解决方案,例如:?您是否考虑(并拒绝)现有解决方案,例如:?您是否会根据当前状态解析行并解释行内容,即如果您以前遇到过(您知道您有元素owl:oneOf
和列表的开头,因此下面是列表元素,直到遇到相应的)
。我建议不要从头开始编写海龟解析器。有各种API已经允许解析,其中许多是开源的,因此您可以直接使用它们或扩展/重用代码以适合您的应用程序。在@david soroko的回答中提到的Sesame和Jena是两个很好的起点。您应该解析这行代码并解释line内容取决于当前状态,即,如果您以前遇到过owl:oneOf(
您知道您有元素owl:oneOf
和列表的开头,那么接下来是列表元素,直到遇到相应的)
。我建议不要从头开始编写海龟解析器。有各种API已经允许解析,其中许多是开源的,因此您可以直接使用它们或扩展/重用代码以适合您的应用程序。在@david soroko的回答中提到的Sesame和Jena是两个很好的起点。是的,我有一个很长的循环。我真的我喜欢StreamTokenizer的想法,但我一定会尝试每种方法,看看哪种方法最有效。非常感谢您给出如此详尽的答案!是的,我还有一段时间要做。我非常喜欢StreamTokenizer的想法,但我一定会尝试每种方法,看看哪种方法最有效。非常感谢您给出如此详尽的答案!