Task 685: .SRX File Format
Task 685: .SRX File Format
The .SRX file format refers to the SPARQL Query Results XML Format, an XML-based format standardized by the W3C for serializing results from SPARQL queries (variable bindings from SELECT queries or boolean results from ASK queries). It uses the namespace http://www.w3.org/2005/sparql-results#.
The properties (elements, attributes, and fields) intrinsic to the .SRX file format are as follows, based on its XML structure:
- Root element:
sparql(with namespacexmlns="http://www.w3.org/2005/sparql-results#"; optionalxsi:schemaLocationattribute for validation). headelement: Contains metadata about query variables and optional links.variableelements: Each with a requirednameattribute (string, e.g., "x") representing a query variable.linkelements: Each with a requiredhrefattribute (relative URI) linking to external metadata.- Either
resultselement (for SELECT queries) orbooleanelement (for ASK queries): resultselement: Contains zero or moreresultelements.resultelement: Represents one query solution, containing zero or morebindingelements.bindingelement: With requirednameattribute (string matching a variable name); contains exactly one child:uri,literal, orbnode.urielement: Text content is the URI string.literalelement: Text content is the literal string; optionalxml:langattribute (language tag) ordatatypeattribute (datatype URI).bnodeelement: Text content is the blank node label (string).booleanelement: Text content is "true" or "false" (case-sensitive).
Two direct download links for example .SRX files:
- https://www.w3.org/2009/sparql/xml-results/output.srx
- https://w3c.github.io/rdf-tests/sparql/sparql10/basic/quotes-4.srx
Here is an embeddable HTML snippet with JavaScript for a Ghost blog (or any web page) that allows drag-and-drop of a .SRX file and dumps all properties to the screen (parses the XML and displays elements, attributes, and values in a readable format):
Drag and drop .SRX file here
- Here is a Python class for handling .SRX files (uses
xml.etree.ElementTreefor parsing/decoding; reads properties, prints them to console, and can write a sample .SRX file):
import xml.etree.ElementTree as ET
class SRXHandler:
NS = '{http://www.w3.org/2005/sparql-results#}'
def __init__(self, filename):
self.filename = filename
self.tree = None
self.root = None
def read_and_decode(self):
self.tree = ET.parse(self.filename)
self.root = self.tree.getroot()
def print_properties(self):
if not self.root:
print("No file loaded.")
return
print(f"Root: sparql (schemaLocation: {self.root.get('{http://www.w3.org/2001/XMLSchema-instance}schemaLocation', 'none')})")
head = self.root.find(f'{self.NS}head')
if head is not None:
print("Head:")
for var in head.findall(f'{self.NS}variable'):
print(f" Variable name: {var.get('name')}")
for link in head.findall(f'{self.NS}link'):
print(f" Link href: {link.get('href')}")
results = self.root.find(f'{self.NS}results')
if results is not None:
print("Results:")
for i, result in enumerate(results.findall(f'{self.NS}result'), 1):
print(f" Result {i}:")
for binding in result.findall(f'{self.NS}binding'):
name = binding.get('name')
child = list(binding)[0]
value = child.text or ''
if child.tag == f'{self.NS}literal':
lang = child.get('{http://www.w3.org/XML/1998/namespace}lang', '')
datatype = child.get('datatype', '')
value += f" (lang: {lang}, datatype: {datatype})"
print(f" Binding {name}: {child.tag.replace(self.NS, '')} = {value}")
boolean = self.root.find(f'{self.NS}boolean')
if boolean is not None:
print(f"Boolean: {boolean.text}")
def write_sample(self, output_filename):
root = ET.Element('sparql', xmlns='http://www.w3.org/2005/sparql-results#')
head = ET.SubElement(root, 'head')
ET.SubElement(head, 'variable', name='x')
results = ET.SubElement(root, 'results')
result = ET.SubElement(results, 'result')
binding = ET.SubElement(result, 'binding', name='x')
ET.SubElement(binding, 'uri').text = 'http://example.org'
tree = ET.ElementTree(root)
tree.write(output_filename, encoding='utf-8', xml_declaration=True)
# Example usage:
# handler = SRXHandler('example.srx')
# handler.read_and_decode()
# handler.print_properties()
# handler.write_sample('output.srx')
- Here is a Java class for handling .SRX files (uses
javax.xml.parsersfor parsing/decoding; reads properties, prints them to console, and can write a sample .SRX file usingTransformer):
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.w3c.dom.Element;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
public class SRXHandler {
private static final String NS = "http://www.w3.org/2005/sparql-results#";
private String filename;
private Document doc;
public SRXHandler(String filename) {
this.filename = filename;
}
public void readAndDecode() throws Exception {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
doc = dBuilder.parse(new File(filename));
doc.getDocumentElement().normalize();
}
public void printProperties() {
if (doc == null) {
System.out.println("No file loaded.");
return;
}
Element root = doc.getDocumentElement();
System.out.println("Root: sparql (schemaLocation: " + root.getAttributeNS("http://www.w3.org/2001/XMLSchema-instance", "schemaLocation") + ")");
NodeList heads = root.getElementsByTagNameNS(NS, "head");
if (heads.getLength() > 0) {
Element head = (Element) heads.item(0);
System.out.println("Head:");
NodeList variables = head.getElementsByTagNameNS(NS, "variable");
for (int i = 0; i < variables.getLength(); i++) {
Element var = (Element) variables.item(i);
System.out.println(" Variable name: " + var.getAttribute("name"));
}
NodeList links = head.getElementsByTagNameNS(NS, "link");
for (int i = 0; i < links.getLength(); i++) {
Element link = (Element) links.item(i);
System.out.println(" Link href: " + link.getAttribute("href"));
}
}
NodeList resultsList = root.getElementsByTagNameNS(NS, "results");
if (resultsList.getLength() > 0) {
Element results = (Element) resultsList.item(0);
System.out.println("Results:");
NodeList resultNodes = results.getElementsByTagNameNS(NS, "result");
for (int i = 0; i < resultNodes.getLength(); i++) {
Element result = (Element) resultNodes.item(i);
System.out.println(" Result " + (i + 1) + ":");
NodeList bindings = result.getElementsByTagNameNS(NS, "binding");
for (int j = 0; j < bindings.getLength(); j++) {
Element binding = (Element) bindings.item(j);
String name = binding.getAttribute("name");
Element child = (Element) binding.getFirstChild().getNextSibling(); // Skip text nodes
String value = child.getTextContent();
String tag = child.getLocalName();
if (tag.equals("literal")) {
String lang = child.getAttributeNS("http://www.w3.org/XML/1998/namespace", "lang");
String datatype = child.getAttribute("datatype");
value += " (lang: " + (lang.isEmpty() ? "" : lang) + ", datatype: " + (datatype.isEmpty() ? "" : datatype) + ")";
}
System.out.println(" Binding " + name + ": " + tag + " = " + value);
}
}
}
NodeList booleans = root.getElementsByTagNameNS(NS, "boolean");
if (booleans.getLength() > 0) {
System.out.println("Boolean: " + booleans.item(0).getTextContent());
}
}
public void writeSample(String outputFilename) throws Exception {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document newDoc = dBuilder.newDocument();
Element root = newDoc.createElementNS(NS, "sparql");
newDoc.appendChild(root);
Element head = newDoc.createElementNS(NS, "head");
root.appendChild(head);
Element var = newDoc.createElementNS(NS, "variable");
var.setAttribute("name", "x");
head.appendChild(var);
Element results = newDoc.createElementNS(NS, "results");
root.appendChild(results);
Element result = newDoc.createElementNS(NS, "result");
results.appendChild(result);
Element binding = newDoc.createElementNS(NS, "binding");
binding.setAttribute("name", "x");
result.appendChild(binding);
Element uri = newDoc.createElementNS(NS, "uri");
uri.setTextContent("http://example.org");
binding.appendChild(uri);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(newDoc);
StreamResult streamResult = new StreamResult(new File(outputFilename));
transformer.transform(source, streamResult);
}
// Example usage:
// public static void main(String[] args) throws Exception {
// SRXHandler handler = new SRXHandler("example.srx");
// handler.readAndDecode();
// handler.printProperties();
// handler.writeSample("output.srx");
// }
}
- Here is a JavaScript class for handling .SRX files (uses
DOMParserfor browser orxml2jsfor Node.js; reads properties, prints them to console, and can write a sample .SRX string to console or file in Node.js):
class SRXHandler {
constructor(filename) {
this.filename = filename;
this.xmlDoc = null;
}
async readAndDecode() {
// For browser: assume file content is passed; for Node.js, use fs
const fs = require('fs'); // Node.js only
const content = fs.readFileSync(this.filename, 'utf8');
const parser = new DOMParser(); // Browser; for Node, use xml2js or similar
this.xmlDoc = parser.parseFromString(content, 'text/xml');
if (this.xmlDoc.getElementsByTagName('parsererror').length > 0) {
console.log('Error parsing XML.');
return;
}
}
printProperties() {
if (!this.xmlDoc) {
console.log('No file loaded.');
return;
}
const NS = 'http://www.w3.org/2005/sparql-results#';
const sparql = this.xmlDoc.getElementsByTagNameNS(NS, 'sparql')[0];
console.log(`Root: sparql (schemaLocation: ${sparql.getAttributeNS('http://www.w3.org/2001/XMLSchema-instance', 'schemaLocation') || 'none'})`);
const head = sparql.getElementsByTagNameNS(NS, 'head')[0];
if (head) {
console.log('Head:');
Array.from(head.getElementsByTagNameNS(NS, 'variable')).forEach(v => {
console.log(` Variable name: ${v.getAttribute('name')}`);
});
Array.from(head.getElementsByTagNameNS(NS, 'link')).forEach(l => {
console.log(` Link href: ${l.getAttribute('href')}`);
});
}
const results = sparql.getElementsByTagNameNS(NS, 'results')[0];
if (results) {
console.log('Results:');
Array.from(results.getElementsByTagNameNS(NS, 'result')).forEach((r, i) => {
console.log(` Result ${i + 1}:`);
Array.from(r.getElementsByTagNameNS(NS, 'binding')).forEach(b => {
const name = b.getAttribute('name');
const child = b.firstElementChild;
let value = child.textContent;
if (child.tagName.endsWith('literal')) {
const lang = child.getAttribute('xml:lang') || '';
const datatype = child.getAttribute('datatype') || '';
value += ` (lang: ${lang}, datatype: ${datatype})`;
}
console.log(` Binding ${name}: ${child.localName} = ${value}`);
});
});
}
const boolean = sparql.getElementsByTagNameNS(NS, 'boolean')[0];
if (boolean) {
console.log(`Boolean: ${boolean.textContent}`);
}
}
writeSample(outputFilename) {
const xml = `<?xml version="1.0"?>
<sparql xmlns="http://www.w3.org/2005/sparql-results#">
<head>
<variable name="x"/>
</head>
<results>
<result>
<binding name="x">
<uri>http://example.org</uri>
</binding>
</result>
</results>
</sparql>`;
if (outputFilename) {
const fs = require('fs'); // Node.js only
fs.writeFileSync(outputFilename, xml);
} else {
console.log(xml);
}
}
}
// Example usage (Node.js):
// const handler = new SRXHandler('example.srx');
// await handler.readAndDecode();
// handler.printProperties();
// handler.writeSample('output.srx');
- Here is a C++ class for handling .SRX files (assumes use of TinyXML-2 library for parsing, as C++ has no built-in XML parser; include tinyxml2.h and link to tinyxml2; reads properties, prints them to console, and can write a sample .SRX file):
#include <iostream>
#include <fstream>
#include "tinyxml2.h" // Assume TinyXML-2 is available: https://github.com/leethomason/tinyxml2
using namespace tinyxml2;
class SRXHandler {
private:
std::string filename;
XMLDocument doc;
public:
SRXHandler(const std::string& fn) : filename(fn) {}
bool readAndDecode() {
if (doc.LoadFile(filename.c_str()) != XML_SUCCESS) {
std::cout << "Error loading file." << std::endl;
return false;
}
return true;
}
void printProperties() {
XMLElement* sparql = doc.FirstChildElement("sparql");
if (!sparql) {
std::cout << "Invalid .SRX format." << std::endl;
return;
}
const char* schemaLoc = sparql->Attribute("xsi:schemaLocation");
std::cout << "Root: sparql (schemaLocation: " << (schemaLoc ? schemaLoc : "none") << ")" << std::endl;
XMLElement* head = sparql->FirstChildElement("head");
if (head) {
std::cout << "Head:" << std::endl;
for (XMLElement* var = head->FirstChildElement("variable"); var; var = var->NextSiblingElement("variable")) {
std::cout << " Variable name: " << var->Attribute("name") << std::endl;
}
for (XMLElement* link = head->FirstChildElement("link"); link; link = link->NextSiblingElement("link")) {
std::cout << " Link href: " << link->Attribute("href") << std::endl;
}
}
XMLElement* results = sparql->FirstChildElement("results");
if (results) {
std::cout << "Results:" << std::endl;
int i = 1;
for (XMLElement* result = results->FirstChildElement("result"); result; result = result->NextSiblingElement("result"), ++i) {
std::cout << " Result " << i << ":" << std::endl;
for (XMLElement* binding = result->FirstChildElement("binding"); binding; binding = binding->NextSiblingElement("binding")) {
const char* name = binding->Attribute("name");
XMLElement* child = binding->FirstChildElement();
std::string tag = child->Name();
std::string value = child->GetText() ? child->GetText() : "";
if (tag == "literal") {
const char* lang = child->Attribute("xml:lang");
const char* datatype = child->Attribute("datatype");
value += " (lang: " + std::string(lang ? lang : "") + ", datatype: " + std::string(datatype ? datatype : "") + ")";
}
std::cout << " Binding " << name << ": " << tag << " = " << value << std::endl;
}
}
}
XMLElement* booleanElem = sparql->FirstChildElement("boolean");
if (booleanElem) {
std::cout << "Boolean: " << (booleanElem->GetText() ? booleanElem->GetText() : "") << std::endl;
}
}
void writeSample(const std::string& outputFilename) {
XMLDocument newDoc;
XMLDeclaration* decl = newDoc.NewDeclaration();
newDoc.InsertFirstChild(decl);
XMLElement* root = newDoc.NewElement("sparql");
root->SetAttribute("xmlns", "http://www.w3.org/2005/sparql-results#");
newDoc.InsertEndChild(root);
XMLElement* head = newDoc.NewElement("head");
root->InsertEndChild(head);
XMLElement* var = newDoc.NewElement("variable");
var->SetAttribute("name", "x");
head->InsertEndChild(var);
XMLElement* results = newDoc.NewElement("results");
root->InsertEndChild(results);
XMLElement* result = newDoc.NewElement("result");
results->InsertEndChild(result);
XMLElement* binding = newDoc.NewElement("binding");
binding->SetAttribute("name", "x");
result->InsertEndChild(binding);
XMLElement* uri = newDoc.NewElement("uri");
uri->SetText("http://example.org");
binding->InsertEndChild(uri);
newDoc.SaveFile(outputFilename.c_str());
}
};
// Example usage:
// int main() {
// SRXHandler handler("example.srx");
// if (handler.readAndDecode()) {
// handler.printProperties();
// }
// handler.writeSample("output.srx");
// return 0;
// }