how to write RDF in original format - rdf4j

RDF4J Newbie question -
When I load this RDF from file:
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<foaf:Person>
<foaf:name>My Name</foaf:name>
</foaf:Person>
</rdf:RDF>
using this code
String fileName = "foaf.rdf";
try {
InputStream is = new FileInputStream(fileName);
Model model = Rio.parse(is, "", RDFFormat.RDFXML);
System.out.println();
Rio.write(model, System.out, RDFFormat.RDFXML);
System.out.println();
is.close();
}
catch (Exception ex) {
System.out.println(ex.toString());
}
the output looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF
xmlns:foaf="http://xmlns.com/foaf/0.1/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:Description rdf:nodeID="node1basf0r6vx1">
<rdf:type rdf:resource="http://xmlns.com/foaf/0.1/Person"/>
<foaf:name rdf:datatype="http://www.w3.org/2001/XMLSchema#string">My Name</foaf:name>
</rdf:Description>
</rdf:RDF>
How would I go about getting RDF printed out in the original format?

RDF4J has also a pretty print function. Maybe this can help you with your output.
You just have to create a writer and then set pretty print to true.
Rio.createWriter(format, outputStream).set(BasicWriterSettings.PRETTY_PRINT, true)

Related

How to set language data with Saxon HE 10.2?

How can I set language data correctly with Saxon HE 10.2? I need the XSLT Processor to output the current date with a month name written out in German, like 21. Oktober 2020. Unfortunately, the processor outputs
[Language: en]21. October 2020.
Saxon PE gives the desired output out of the box.
This is my XSLT code:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="3.0">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:value-of select="format-dateTime(current-dateTime(), '[D]. [MNn] [Y]', 'de', (), ())"/>
</xsl:template>
</xsl:stylesheet>
The test XML source code file is like this:
<?xml version="1.0" encoding="UTF-8"?>
<root/>
In Linux, I run java -cp $xsltProc $class -s:source.xml -xsl:stylesheet.xslt -o:result.
$xsltProc is the path to the file saxon-he-10.2.jar.
$class is net.sf.saxon.Transform.
Any help would be greatly appreciated.
To support German date formats "out of the box", you need Saxon-PE or higher.
See https://saxonica.com/documentation/index.html#!extensibility/config-extend/localizing/other-numberings
If you want this with Saxon-HE, you can compile the open source code for class net.sf.saxon.option.local.Numberer_de and register it with the Configuration:
configuration.setLocalizerFactory(new LocalizerFactory() {
public Numberer getNumberer(String language, String country) {
if (lang.equals("de")) {
return new Numberer_de();
} else {
...
}
});
The Numberer code is available at https://saxonica.plan.io/projects/saxon/repository/he/revisions/master/entry/latest10/hej/net/sf/saxon/option/local/Numberer_de.java
I tried the following with the example files from the original question, but the Configuration was never invoked.
I presume the Configuration needs to be registered somehow?
final Configuration config = new Configuration();
/**/ config.setLocalizerFactory(new LocalizerFactory() {
public Numberer getNumberer(final String language, final String country) {
if (language.equals("de")) {
return Numberer_de.getInstance();
} else {
return null;
}
}
});
Transform.main(new String[] {
"-s:source.xml",
"-xsl:stylesheet.xslt",
"-o:result.txt"
});

How to transform XML document with CDATA using JDOM2?

Source document:
<content><![CDATA[>&< test]]></content>
XSLT document (cdata-transformation.xslt):
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" cdata-section-elements="transformed" />
<xsl:template match="/content">
<transformed>
<xsl:value-of select="." />
</transformed>
</xsl:template>
</xsl:stylesheet>
Wanted result:
<?xml version="1.0" encoding="UTF-8"?>
<transformed><![CDATA[>&< test]]></transformed>
Actual result:
<?xml version="1.0" encoding="UTF-8"?>
<transformed>>&< test</transformed>
Code used to test using JDOM2:
import java.io.IOException;
import java.io.InputStream;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import org.jdom2.CDATA;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;
import org.jdom2.output.XMLOutputter;
import org.jdom2.transform.JDOMResult;
import org.jdom2.transform.JDOMSource;
import org.junit.Test;
public class CdataTransformationTest {
#Test
public void learning_cdataTransformationWithJdom() throws Exception {
Document xslt = loadResource("xslt/cdata-transformation.xslt");
Document source = new Document(new Element("content")
.addContent(new CDATA(">&< test")));
Document transformed = transform(source, xslt);
XMLOutputter outputter = new XMLOutputter();
System.out.println(outputter.outputString(transformed));
}
private static Document transform(Document sourceDoc, Document xsltDoc) throws TransformerException {
JDOMSource source = new JDOMSource(sourceDoc);
JDOMResult result = new JDOMResult();
Transformer transformer = TransformerFactory.newInstance()
.newTransformer(new JDOMSource(xsltDoc));
transformer.transform(source, result);
return result.getDocument();
}
private static Document loadResource(String resource) throws IOException, JDOMException {
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
InputStream inputStream = classloader.getResourceAsStream(resource);
if (inputStream != null) {
try {
SAXBuilder builder = new SAXBuilder();
return builder.build(inputStream);
} finally {
inputStream.close();
}
} else {
return null;
}
}
}
JDOM version used:
<dependency>
<groupId>org.jdom</groupId>
<artifactId>jdom2</artifactId>
<version>2.0.6</version>
</dependency>
XSLT processor used:
<dependency>
<groupId>xalan</groupId>
<artifactId>xalan</artifactId>
<version>2.7.1</version>
</dependency>
I have searched around for ways to do this, and the best answers say that what is needed to wrap content in CDATA is to add the tag name in the cdata-section-elements attribute. I cannot get this to work with JDOM and not when using the Free online XSL Transformer either. I have also tried using saxon instead of xalan, but with the same result.
Why doesn't this work? What am I missing/doing wrong here? Is JDOM ignoring the cdata-section-elements attribute?
I have also tried wrapping the content like this:
<xsl:text disable-output-escaping="yes"><![CDATA[</xsl:text>
<xsl:value-of select="." />
<xsl:text disable-output-escaping="yes">]]></xsl:text>
But this produces an unwanted result in JDOM which makes it difficult to work with. Visible when you set the outputer.getFormat().setIgnoreTrAXEscapingPIs(true); and it looks really ugly when using pretty format.
<?xml version="1.0" encoding="UTF-8"?>
<transformed>
<?javax.xml.transform.disable-output-escaping?>
<![CDATA[
<?javax.xml.transform.enable-output-escaping?>
>&< test
<?javax.xml.transform.disable-output-escaping?>
]]>
<?javax.xml.transform.enable-output-escaping?>
</transformed>
You are transforming to a JDOMResult, that is, a tree representation, and not to a stream or file. Output directives like cdata-section-elements are only used when the XSLT processor serializes the result to a stream or file, but not when building a result tree in memory. So I think if you want to construct CDATA sections as the result of XSLT with cdata-section-elements, you need to make sure you write to a file or stream or at least a StringWriter, then you could load the JDOM result from that file or stream respectively created String.
Rewriting the transform method to:
private static Document transform(Document sourceDoc, Document xsltDoc) throws JDOMException, IOException, TransformerException {
StringWriter writer = new StringWriter();
JDOMSource source = new JDOMSource(sourceDoc);
Result result = new StreamResult(writer);
Transformer transformer = TransformerFactory.newInstance()
.newTransformer(new JDOMSource(xsltDoc));
transformer.transform(source, result);
SAXBuilder builder = new SAXBuilder();
return builder.build(new StringReader(writer.toString()));
}

How to convert json data from Poco c++ json to XML?

I want to use Poco::JSON in my project to convert the received json from server to XML format for manipulation in the code . I have'nt yet tried Poco::JSON. Please provide some pointer to accomplish this.
Here is a quick implementation of JSON to XML handler. Use it (with caution, this is not production code) like this:
#include "JSON2XMLConverter.h"
#include "Poco/JSON/Parser.h"
using Poco::JSON::Parser;
using Poco::JSON::Handler;
int main()
{
std::string json = "{ \"name\" : \"Homer\", \"age\" : 38, \"wife\" : \"Marge\", \"age\" : 36, \"children\" : [ \"Bart\", \"Lisa\", \"Maggie\" ] }";
Handler::Ptr pJ2XConv = new JSON2XMLConverter(std::cout);
Parser(pJ2XConv).parse(json);
return 0;
}
Output (formatting added, not generated by code):
<?xml version="1.0" encoding="UTF-8"?>
<root>
<name>Homer</name>
<age>38</age>
<wife>Marge</wife>
<age>36</age>
<children>
<children1>Bart</children1>
<children2>Lisa</children2>
<children3>Maggie</children3>
</children>
</root>

JAXP pipeline ignores xsl:comment's (using Saxon HE 9.5.1-4)

When using JAXP pipelin (using Saxon HE), the comments created with don't appear in the resulted .xml.
First I set the system properties to get info and use Saxon and define the input/output:
System.setProperty("jaxp.debug", "1");
System.setProperty("javax.xml.transform.TransformerFactory", "net.sf.saxon.TransformerFactoryImpl");
StreamSource xsl = ...
StreamResult output = ...
InputSource input = ...
Then I have the following construction with dummy Pre and Post filters:
TransformerFactory factory = TransformerFactory.newInstance();
SAXTransformerFactory saxFactory = (SAXTransformerFactory) factory;
SAXParserFactory parserFactory = SAXParserFactory.newInstance();
parserFactory.setNamespaceAware(true);
XMLReader parser = parserFactory.newSAXParser().getXMLReader();
XMLFilter pre = new XMLFilterImpl(parser);
XMLFilter xslFilter = saxFactory.newXMLFilter(xsl);
xslFilter.setParent(pre);
XMLFilter post = new XMLFilterImpl(xslFilter);
TransformerHandler serializer = saxFactory.newTransformerHandler();
serializer.setResult(output);
Transformer trans = serializer.getTransformer();
trans.setOutputProperty(OutputKeys.METHOD, "xml");
post.setContentHandler(serializer);
post.parse(input);
When run with the following stylesheet:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:comment>Nice comment</xsl:comment>
<test>[<xsl:value-of select="system-property('xsl:vendor')" />]
(<xsl:value-of select="system-property('xsl:version')" />
)[<xsl:value-of select="system-property('xsl:vendor-url')" />]</test>
</xsl:template>
</xsl:stylesheet>
I get the follwing output.xml without the comment:
<?xml version="1.0" encoding="UTF-8"?>
<test>[Saxonica]
(2.0
)[http://www.saxonica.com/]
</test>
And the following console log:
JAXP: find factoryId =javax.xml.transform.TransformerFactory
JAXP: found system property, value=net.sf.saxon.TransformerFactoryImpl
JAXP: created new instance of class net.sf.saxon.TransformerFactoryImpl using ClassLoader: null
JAXP: find factoryId =javax.xml.parsers.SAXParserFactory
JAXP: loaded from fallback value: com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl
JAXP: created new instance of class com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl using ClassLoader: null
JAXP: find factoryId =javax.xml.parsers.SAXParserFactory
JAXP: loaded from fallback value: com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl
JAXP: created new instance of class com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl using ClassLoader: null
When run without the whole pipeline, I do get the coment:
javax.xml.transform.TransformerFactory tFactory = javax.xml.transform.TransformerFactory.newInstance();
javax.xml.transform.Transformer transformer = tFactory.newTransformer(xsl);
transformer.transform(input, output);
results in
<?xml version="1.0" encoding="UTF-8"?><!--Nice comment -->
<test>[Saxonica]
(2.0
)[http://www.saxonica.com/]
</test>
Does anyone know why the JAXP pipeline omits the comments?
The SAX2 ContentHandler interface does not receive notification of comments. For that you need a LexicalHandler. But the SAX2 helper class XMLFilterImpl does not implement LexicalHandler, so it effectively drops the comments.
Switch to s9api in place of JAXP - it does these things much better.

Getting 'WrappedRuntimeException' when using XSL-FO in an Xpage

I am trying to create a PDF from the contents of an xpage. I am following the format that Paul Calhoun used in Notes in 9 #102. I am able to create PDF's for views, but having trouble creating one for a document. I do not think the error is in Paul's code so I am not including it here, although I can if need be.
To generate the XML to display I use the generateXML() method of the document class in java. I get a handle to the backend document and then return the XML. The XML appears well formed, the top level tab is <document>. I pass this XML to the transformer which is using Apache FOP. All of my code is contained in the beforeRenderResponse of an xAgent.
The XSL stylesheet that I am using is a stripped down version to just get a proof of concept to work. I am going to include it, because the problem likely resides with this code. I am totally new to XSL.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.1"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
exclude-result-prefixes="fo">
<xsl:output
method="xml"
version="1.0"
omit-xml-declaration="no"
indent="yes" />
<xsl:param
name="versionParam"
select="'1.0'" />
<xsl:template match="document">
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
<fo:layout-master-set>
<fo:simple-page-master
master-name="outpage"
page-height="11in"
page-width="8.5in"
margin-top="1in"
margin-bottom="1in"
margin-left="1in"
margin-right="1in">
<fo:region-body />
</fo:simple-page-master>
</fo:layout-master-set>
<fo:page-sequence master-reference="A4">
<fo:block
font-size="16pt"
font-weight="bold"
space-after="5mm">
Apache FOP Proof of Concept.
</fo:block>
</fo:page-sequence>
</fo:root>
</xsl:template>
</xsl:stylesheet>
In the log file I get the message:
FATAL ERROR: 'com.ibm.xtq.common.utils.WrappedRuntimeException: D:\Program Files\IBM\Domino\<document form='PO'>
The error echos the entire XML in the log that it is trying to transform and ends with:
(The filename, directory name, or volume label syntax is incorrect.)'
Notice that Domino is trying to include the XML in a path. I know this is wrong, but don't know what to do to fix it.
EDIT: This is the Java class that runs the transformation. This code is from Paul Calhoun's demo.
import java.io.OutputStream;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamSource;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
public class DominoXMLFO2PDF {
public static void getPDF(OutputStream pdfout,String xml,String xslt, Boolean authReq, String usernamepass) {
try {
//System.out.println("Transforming...");
Source xmlSource,xsltSource; //Source xmlSource = new StreamSource("http://localhost/APCC.nsf/Main?ReadViewEntries&count=999&ResortAscending=2");
xmlSource = new StreamSource(xml); //Source xsltSource = new StreamSource("http://localhost/APCC.nsf/viewdata.xsl");
xsltSource = new StreamSource(xslt);// configure fopFactory as desired
final FopFactory fopFactory = FopFactory.newInstance();
FOUserAgent foUserAgent = fopFactory.newFOUserAgent();
// configure foUserAgent as desired
// Setup output
// OutputStream out = pdfout;
// out = new java.io.BufferedOutputStream(out);
try {
// Construct fop with desired output format
Fop fop = fopFactory.newFop(org.apache.xmlgraphics.util.MimeConstants.MIME_PDF,foUserAgent, pdfout);
// Setup XSLT
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(xsltSource);
//transformer.setParameter("versionParam", "Company List"); // Set the value of a <param> in the stylesheet
Source src = xmlSource; // Setup input for XSLT transformation
Result res = new SAXResult(fop.getDefaultHandler()); // Resulting SAX events (the generated FO) must be piped through to FOP
transformer.transform(src, res); // Start XSLT transformation and FOP processing
} catch (Exception e) {
} finally {
}
} catch (Exception e) {
e.printStackTrace(System.err);
}
}
}
This code is called in the xAgent using this line:
var retOutput = jce.getPDF(pageOutput, xmlsource, xsltsource, authReq, usernamepass);
The xmlsource is set with this line where the method returns XML using Document.generateXML():
var xmlsource = statusBean.generateXML(POdata, sessionScope.unidPDF);
Your problem is the XMLSource! When you look at Paul's code:
Source xmlSource = new StreamSource("http://localhost/APCC.nsf/Main?ReadViewEntries");
This points to an URL where to retrieve XML.On the other hand your code:
xmlsource = statusBean.generateXML(POdata, sessionScope.unidPDF);
contains the XML. So you need to change to:
String xmlstring = statusBean.generateXML(POdata, sessionScope.unidPDF);
Source xmlsource = new StreamSource(new java.io.StringReader(xmlstring));
I strongly suggest you try to keep all the Java in a java class, so you don't need to wrap/upwrap the objects in SSJS. Have a look at my series on FO too.