【问题标题】:Java - Jena API - Output fileJava - Jena API - 输出文件
【发布时间】:2012-09-02 13:05:59
【问题描述】:

我正在使用 Java 和 Jena API。

我有一个类Person,其数据类型属性为hasFirstNamehasLastNamehasDateOfBirthhasGender

这是一个人在我的 RDF 文件中的表示方式。

<rdf:Description rdf:about="http://www.fam.com/FAM#Bruno04/02/1980 ">
    <j.0:FAMhasGender>H</j.0:FAMhasGender>
    <j.0:FAMhasDateOfBirth>04/02/1980</j.0:FAMhasDateOfBirth>
    <j.0:FAMhasLastName>DS </j.0:FAMhasLastName>
    <j.0:FAMhasFirstName> Bruno</j.0:FAMhasFirstName>
 </rdf:Description>

对于每个性别为女性的人,我想生成一个带有以下行的文本文件:

[label= \"" +firstName+ " \"\n\n\"D.Naiss:"+dnai1+"\", "+shape2+"]

因此,例如,如果有 3 位女性,则该文件必须包含 3 行具有该格式的行。形状值(然后是输出线)将取决于性别,这就是为什么我不能对两种性别都使用同一条线。

对于每个性别为男性的人,我想在下面输出这一行:

[label= \"" +firstName+ " \"\n\n\"D.Naiss:"+dnai1+"\", "+**shape**+"]

我遇到的问题是在输出文件中我只看到一个女人和一个男人有相应的行。我有不止一个女人和男人,但他只为每个性别输出一个。那是我的问题...

以下是相关代码:

public void accessProp() {

    readFile(inputFile); // rdf
    String fname;
    String dd;
    String gen;

    ExtendedIterator instances = onto.person.listInstances();
    Individual instance = null;
    Individual firstInstance = null;
    while (instances.hasNext()) {
        instance = (Individual) instances.next();

        gen = instance.getPropertyValue(onto.hasGender).toString();
        fname = instance.getPropertyValue(onto.hasFirstName).toString();
        dd = instance.getPropertyValue(onto.hasDateOfBirth).toString();

        writeFile(fname, dd, genr);
    }
}

// Write text file
public void writeFile(String fn, String dbir, String gn) {
    String fileout = "D:/file1.txt";
    String firstName = fn;
    String dateB = dbir;
    String gender = gn;

    BufferedWriter out;
    try {
        out = new BufferedWriter(new FileWriter(fileout, true));

        if (gender.equals("F")) {
            out.write("[label= \"" + firstName + " \"\n\n\"D.Naiss:" + dnai1 + "\", " + shape + "]");
        } else if (gender.equals("M")) {
            out.write("[label= \"" + firstName + " \"\n\n\"D.Naiss:" + dnai1 + "\", " + shape2 + "]");
        }

        out.newLine();

        // flushes and closes the stream
        out.close();
    } catch (IOException e) {
        System.out.println("There was a problem:" + e);
    }
}

你能告诉我应该修改什么来解决我的问题吗?

谢谢

【问题讨论】:

  • 由于您仍然没有其他答案,我建议您仔细阅读我的。我认为问题出在您的输入上,实际上我建议修改 while(i.hasNext) System.out.println(i.next()) 中的 while 循环以计算实例。无论如何,你真的必须在某个时候学习 RDF——这就是为什么我认为我的回答可以成为寻找学习资源的一个很好的起点。在 SO 上没有向导:我们需要可以在我们的机器上运行(和崩溃)的错误描述、堆栈跟踪和独立的测试用例

标签: java file-io rdf jena


【解决方案1】:

我的拙见是您完全不了解 RDF,并且当您无法自己找出问题所在时,您正在努力通过在 SO 上提出随机问题来使事情正常进行。这种态度并没有错,但是如果您尝试仔细阅读文档(OWL、RDF 和 Jena),会更好。

我怀疑问题不是在 Java 方面,而是你的本体有问题(除非你能证明它不是真的)。​​

我从来没有使用过 RDF 和 Jena,但是我花了几个小时阅读文档,所以即使以下可能不是做事的神圣方式,它肯定比你的方式更好。当您无法理解某些内容时,请随意提问(向我或 SO 社区)。首先,让我们在 OWL 中编写我们的本体(我是新手,所以这可能包含错误)注意:您不应该在每次程序运行时都使用 Java 代码构建本体。您可能会从以下序列化表单中加载您的本体

<?xml version="1.0"?>
<!-- See http://www.w3.org/TR/2004/REC-owl-guide-20040210/#Namespaces -->
<!DOCTYPE rdf:RDF [
<!ENTITY fam "http://zybnet.com/fam#" >
<!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" >
]>
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
    xmlns:owl="http://www.w3.org/2002/07/owl#"
    xmlns:xsd="&xsd;"

    xmlns    ="&fam;" 
    xmlns:fam="&fam;" 
    xml:base ="&fam;" >

    <owl:Class rdf:about="Person" />

    <!-- Properties name, gender, and birth -->
    <owl:DatatypeProperty rdf:about="&fam;name">
        <rdfs:domain rdf:resource="Person" />
        <rdfs:range  rdf:resource="&xsd;string" />
    </owl:DatatypeProperty>
    <owl:DatatypeProperty rdf:about="&fam;birth">
        <rdfs:domain rdf:resource="Person" />
        <rdfs:range  rdf:resource="&xsd;date" />
    </owl:DatatypeProperty>
    <owl:DatatypeProperty rdf:about="&fam;gender">
        <rdfs:domain rdf:resource="Person" />
        <rdfs:range  rdf:resource="&xsd;string"/>
    </owl:DatatypeProperty>

    <rdf:Description rdf:about="user/7192">
        <fam:name>Bruno</fam:name>
        <fam:gender>M</fam:gender>
        <fam:birth>19/08/1987</fam:birth>
    </rdf:Description>
    <rdf:Description rdf:about="user/3023">
        <fam:name>Raffaele</fam:name>
        <fam:gender>M</fam:gender>
        <fam:birth>09/02/1927</fam:birth>
    </rdf:Description>
    <rdf:Description rdf:about="user/9283">
        <fam:name>Angela</fam:name>
        <fam:gender>F</fam:gender>
        <fam:birth>01/06/1957</fam:birth>
    </rdf:Description>
</rdf:RDF>

然后是Java代码

public class RDF {
    public static void main(String[] args) {
        Model model = ModelFactory.createOntologyModel();
        model.read(RDF.class.getResourceAsStream("family.rdf"), null);

        System.out.println("All triples in file");

        outQuery("SELECT ?subject ?predicate ?object " +
                "WHERE { ?subject ?predicate ?object }", model);

        System.out.println("A simple query");

        outQuery("SELECT ?subject ?name ?gender " +
                "WHERE { " +
                " ?subject <http://zybnet.com/fam#name> ?name ." +
                " ?subject <http://zybnet.com/fam#gender> ?gender ." +
                " }", model);
    }

    private static void outQuery(String q, Model model) {
        Query query = QueryFactory.create(q);
        QueryExecution execution = QueryExecutionFactory.create(query, model);
        ResultSet results = execution.execSelect();
        ResultSetFormatter.out(System.out, results, query);
        execution.close();
    }

}

最后是一些 log4j 配置(这必须放在类路径上的 log4j.properties 中,或者使用 PropertyConfigurator.configure 从 Java 代码中加载)

log4j.logger.com.hp.hpl.jena=debug, console

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%-5p] %m%n

这应该是您的起始代码。通过运行它,您将看到发生了什么。通过了解此代码,您将能够重构您的应用程序并找到要研究的内容来启动和运行它。祝你好运!

示例输出:(文本已从简洁中删除)

[Lots of text here...]
A simple query
[DEBUG] Lock : main
-------------------------------------------------------
| uri                           | name       | gender |
=======================================================
| <http://zybnet.com/user/9230> | "Angela"   | "F"    |
| <http://zybnet.com/user/0239> | "Raffaele" | "M"    |
| <http://zybnet.com/user/0001> | "Bruno"    | "M"    |
-------------------------------------------------------

【讨论】:

    【解决方案2】:

    您在writeFile 中关闭您的输出文件,因此在第一次调用此方法后无法再写入数据。在accessProp 中的主循环之后关闭文件。

    【讨论】:

    • 实际上,在我看来,他以附加模式打开一个文件,然后将其关闭。当然,这不是应该的方式,但这不应该是他的问题。
    • @Denis Tulskiy 感谢您的回答。我想,我不明白你的解释。你的意思是我必须把它拿出来。close();在 accessProp 中?
    • @Raffaele,对,没看到文件是以附加模式打开的。
    • @user1632278:不,对不起,我的回答似乎是错误的。执行过程中是否有异常?
    • 执行过程中没有异常。它输出文本文件,但它不包含所有女性和男性,只有一位女性和一位男性。 :(
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-07
    • 2011-01-19
    • 1970-01-01
    • 2013-09-05
    相关资源
    最近更新 更多