在java中将xml:base添加到xml文件

在java中将xml:base添加到xml文件,java,xml,jena,Java,Xml,Jena,我想向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="

我想向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">

我希望它看起来像这样:

<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">

我一定是在放屁什么的,因为我想不出一个实用的好方法


有什么想法吗?

经过一番挖掘,我就是这么做的

注意:我让第三方应用程序将xml写入StringWriter,而不是名为“writer”的输出流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);

我真的认为这会更容易。

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();

您可以通过获取适当的RDFWriter并将其
xmlbase
属性设置为所选的
xmlbase
来更改RDF/xml序列化中使用的
xml:base
。下面的代码从字符串中读取模型(这个问题的重要部分是关于如何编写模型,而不是它来自何处frm),然后在RDF/XML中写入两次,每次都使用不同的
XML:base

import java.io.ByteArrayInputStream;
导入java.io.IOException;
导入java.io.InputStream;
导入com.hp.hpl.jena.rdf.model.model;
导入com.hp.hpl.jena.rdf.model.ModelFactory;
导入com.hp.hpl.jena.rdf.model.RDFWriter;
公共类变更库{
公共静态void main(字符串[]args)引发IOException{
最后一个字符串NS=”http://example.org/";
最终字符串text=“”+
“@前缀ex:。\n”+
“ex:foo a ex:foo。\n”+
“ex:foo ex:frob ex:bar.\n”;
最终模型=ModelFactory.createDefaultModel();
try(final InputStream in=new ByteArrayInputStream(text.getBytes())){
model.read(in,null,“TTL”);
}
//获取RDF/XML-ABBREV的编写器,将其xmlbase设置为NS,然后编写模型
RDFWriter-writer=model.getWriter(“RDF/XML-ABBREV”);
writer.setProperty(“xmlbase”,NS);
writer.write(model、System.out、null);
//将base更改为example.com(.com,not.org)并再次写入
writer.setProperty(“xmlbase”http://example.com" );
writer.write(model、System.out、null);
}
}
输出是(注意,在第一种情况下,基是
htttp://example.org/
第二种情况是
http://example.com
(区别在于.org与.com):



这比您发布的另一个答案要短,但比这更简单。一旦您阅读了模型,您只需设置writer的
xmlbase
属性,并使用writer编写模型。我添加了这一点。