0

Java で xml ファイルに xml:base 宣言を追加したいと考えています。現在、サードパーティのコードによって生成された OutputStream に xml 出力があります。

ファイルは次のように始まります。

<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:owl="http://www.w3.org/2002/07/owl#"
    xmlns="http://www.mycompany.com/myNS#"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">

そして、私はそれを次のようにしたい:

<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:owl="http://www.w3.org/2002/07/owl#"
    xmlns="http://www.mycompany.com/myNS#"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
    xml:base="http://www.mycompany.com/myNS">

実用的にこれを行う良い方法が思いつかないので、私は脳のおならか何かを持っているに違いありません。

何か案は?

4

3 に答える 3

1

xml:base適切な RDFWriter を取得し、そのxmlbaseプロパティを選択した に設定することにより、RDF/XML シリアライゼーションで使用されるを変更できますxmlbase。次のコードは、文字列からモデルを読み取り (この質問の重要な部分は、モデルがどこから来たかではなく、モデルをどのように記述するかということです)、RDF/XML で 2 回、毎回異なるxml:base.

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;

import com.hp.hpl.jena.rdf.model.Model;
import com.hp.hpl.jena.rdf.model.ModelFactory;
import com.hp.hpl.jena.rdf.model.RDFWriter;

public class ChangeBase {
    public static void main(String[] args) throws IOException {
        final String NS = "http://example.org/";
        final String text = "" +
                "@prefix ex: <"+NS+">.\n" +
                "ex:foo a ex:Foo .\n" +
                "ex:foo ex:frob ex:bar.\n"; 
        final Model model = ModelFactory.createDefaultModel();
        try ( final InputStream in = new ByteArrayInputStream( text.getBytes() )) {
            model.read( in, null, "TTL" );
        }
        // get a writer for RDF/XML-ABBREV, set its xmlbase to the NS, and write the model
        RDFWriter writer = model.getWriter( "RDF/XML-ABBREV" );
        writer.setProperty( "xmlbase", NS );
        writer.write( model, System.out, null );

        // change the base to example.com (.com, not .org) and write again
        writer.setProperty( "xmlbase", "http://example.com" );
        writer.write( model, System.out, null );
    }
}

htttp://example.org/出力は次のとおりです (最初のケースでは base が、2 番目のケースではhttp://example.com(違いは .org と .comであることに注意してください):

<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:ex="http://example.org/"
  xml:base="http://example.org/">
  <ex:Foo rdf:about="foo">
    <ex:frob rdf:resource="bar"/>
  </ex:Foo>
</rdf:RDF>
<rdf:RDF
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:ex="http://example.org/"
  xml:base="http://example.com">
  <ex:Foo rdf:about="http://example.org/foo">
    <ex:frob rdf:resource="http://example.org/bar"/>
  </ex:Foo>
</rdf:RDF>
于 2013-09-24T17:12:07.207 に答える
-1

ByteArrayInputStream は大きなファイルに対応できません。また、一時ファイルを使用するというアイデアも好きではありませんでした。xml:baseまた、タグ を追加するためだけにファイル全体を DOM にロードするのはやり過ぎだと思いました。

これは、パイプと単純な手巻きの解析コードを使用してタグを追加する代替ソリューションです。

PipedInputStream pipedInput = new PipedInputStream();
PipedOutputStream pipedOutput = new PipedOutputStream(pipedInput);
new Thread(new ModelExportThread(model, pipedOutput)).start();
int bufferSize = 1024;
byte[] bytes = new byte[bufferSize];            
StringBuffer stringBuffer = new StringBuffer();
int bytesRead = pipedInput.read(bytes, 0, bufferSize);
boolean done = false;
String startRDF = "<rdf:RDF";
while (bytesRead > 0) {
    if (!done) {
        stringBuffer.append(new String(bytes, 0, bytesRead));
        int startIndex = stringBuffer.indexOf(startRDF);
        if ((startIndex >= 0)) {
            stringBuffer.insert(startIndex + startRDF.length(), " xml:base=\"" + namespace + "\"");
            outputStream.write(stringBuffer.toString().getBytes());
            stringBuffer.setLength(0);
            done = true;
        }
    } else {
        outputStream.write(bytes, 0, bytesRead);
    }
    bytesRead = pipedInput.read(bytes, 0, bufferSize);
}
outputStream.flush();

出力パイプに書き込むスレッド化されたコードを次に示します。

public class ModelExportThread implements Runnable {

    private final OntModel model;
    private final OutputStream outputStream;

    public ModelExportThread(OntModel model, OutputStream outputStream) {
        this.model = model;
        this.outputStream = outputStream;
    }

    public void run() {
        try {
            model.write(outputStream, "RDF/XML-ABBREV");
            outputStream.flush();
            outputStream.close();
        } catch (IOException ex) {
            Logger.getLogger(OntologyModel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

}
于 2009-04-06T19:35:48.040 に答える
-1

掘り下げた後、これが私がしたことです。

注: サード パーティのアプリで、xml を「writer」という名前の出力ストリームではなく StringWriter に書き込むようにしました。「outputStream」は、結果の XML が書き込まれるストリームの名前です。

ByteArrayInputStream inputStream = new ByteArrayInputStream(writer.toString().getBytes());
Document myXML = 
     DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(inputStream);
myXML.getDocumentElement().setAttribute("xml:base", namespace);
Transformer transformer = TransformerFactory.newInstance().newTransformer();
StreamResult result = new StreamResult(outputStream);
DOMSource source = new DOMSource(myXML);
transformer.transform(source, result);

これはもっと簡単だろうと本当に思いました。

于 2009-04-03T20:08:30.123 に答える