diff --git a/pom.xml b/pom.xml
index 60b8ceac..a7d8b930 100644
--- a/pom.xml
+++ b/pom.xml
@@ -401,6 +401,14 @@
1.6.3
+
+
+ com.ximpleware
+ vtd-xml
+ 2.13.4
+
+
+
diff --git a/sparql-anything-xml/pom.xml b/sparql-anything-xml/pom.xml
index 9db06ffc..43cfeffe 100644
--- a/sparql-anything-xml/pom.xml
+++ b/sparql-anything-xml/pom.xml
@@ -33,10 +33,24 @@
sparql-anything-model
${project.version}
+
+
+
+ com.ximpleware
+ vtd-xml
+
+
junit
junit
- 4.13.1
+ test
+
+
+
+
+ com.github.sparqlanything
+ sparql-anything-testutils
+ ${project.version}
test
diff --git a/sparql-anything-xml/src/main/java/com/github/sparqlanything/xml/XMLTriplifier.java b/sparql-anything-xml/src/main/java/com/github/sparqlanything/xml/XMLTriplifier.java
index fa369692..52c4632c 100644
--- a/sparql-anything-xml/src/main/java/com/github/sparqlanything/xml/XMLTriplifier.java
+++ b/sparql-anything-xml/src/main/java/com/github/sparqlanything/xml/XMLTriplifier.java
@@ -22,8 +22,20 @@
package com.github.sparqlanything.xml;
import com.github.sparqlanything.model.FacadeXGraphBuilder;
+import com.github.sparqlanything.model.Slice;
+import com.github.sparqlanything.model.Slicer;
import com.github.sparqlanything.model.Triplifier;
import com.github.sparqlanything.model.TriplifierHTTPException;
+import com.ximpleware.AutoPilot;
+import com.ximpleware.EncodingException;
+import com.ximpleware.NavException;
+import com.ximpleware.ParseException;
+import com.ximpleware.VTDGen;
+import com.ximpleware.VTDNav;
+import com.ximpleware.XPathEvalException;
+import com.ximpleware.XPathParseException;
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.lang3.StringUtils;
import org.apache.jena.ext.com.google.common.collect.Sets;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -44,20 +56,136 @@
import java.util.Deque;
import java.util.HashMap;
import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
-public class XMLTriplifier implements Triplifier {
+public class XMLTriplifier implements Triplifier, Slicer {
private static final Logger log = LoggerFactory.getLogger(XMLTriplifier.class);
- @Override
- public void triplify(Properties properties, FacadeXGraphBuilder builder) throws IOException, TriplifierHTTPException {
-// URL url = Triplifier.getLocation(properties);
-//
-// if (url == null)
-// return;
+ public void transformWithXPath(List xpaths, Properties properties, FacadeXGraphBuilder builder) throws IOException, TriplifierHTTPException {
+
+ String namespace = Triplifier.getNamespaceArgument(properties);
+ String dataSourceId = Triplifier.getRootArgument(properties);
+ String root = Triplifier.getRootArgument(properties);
+
+ builder.addRoot(dataSourceId, root);
+ try {
+ VTDGen vg = new VTDGen();
+ byte[] bytes = IOUtils.toByteArray(Triplifier.getInputStream(properties));
+ vg.setDoc(bytes);
+ vg.parse(false);
+ VTDNav vn = vg.getNav();
+ Iterator xit = xpaths.iterator();
+ while(xit.hasNext()) {
+ String xpath = xit.next();
+ log.debug("Evaluating XPath: {}", xpath);
+ // vg.parse(false); // set namespace awareness to true
+ AutoPilot ap = new AutoPilot(vn);
+ //ap.declareXPathNameSpace("ns1","http://purl.org/dc/elements/1.1/");
+ ap.selectXPath(xpath);
+ int result = -1;
+ int count = 1;
+ while ((result = ap.evalXPath()) != -1) {
+ transformFromXPath(vn, result, count, root, dataSourceId, properties, builder);
+ count++;
+ }
+ log.debug("XPath: {} matches", count);
+ }
+
+ } catch (XPathEvalException | NavException | ParseException | XPathParseException e){
+ log.error("Error while evaluating XPath expression");
+ throw new IOException(e);
+ }
+ }
+
+ public int transformFromXPath(VTDNav vn, int result, int child, String parentId, String dataSourceId, Properties properties, FacadeXGraphBuilder builder) throws NavException {
+ log.trace(" -- index: {} type: {}", result, vn.getTokenType(result));
+ switch (vn.getTokenType(result)) {
+ case VTDNav.TOKEN_STARTING_TAG:
+ String tag = vn.toString(result);
+ log.trace(" -- tag: {} ", tag);
+ String childId = String.join("", parentId , "/" , Integer.toString(child), ":", tag);
+ builder.addContainer(dataSourceId, parentId, child, childId);
+
+ // Attributes
+ int attrCount = vn.getAttrCount();
+ log.trace(" -- attr count: {}", attrCount);
+ int increment = 0;
+ if (attrCount > 0) {
+ for (int i = result + 1; i <= result + attrCount; i += 2) {
+ // Not sure why but sometime attrCount is not reliable
+ if(vn.getTokenType(i) != VTDNav.TOKEN_ATTR_NAME){
+ break;
+ }
+ String key = vn.toString(i);
+ String value = vn.toString(i + 1);
+ log.trace(" -- attr: {} = {}", key, value);
+ builder.addValue(dataSourceId, childId, key, value);
+ increment += 2;
+ }
+ }
+ // Get the text
+ int t = vn.getText(); // get the index of the text (char data or CDATA)
+ if (t != -1) {
+ String text = vn.toNormalizedString(t);
+ log.trace(" -- text: {}", text);
+ builder.addValue(dataSourceId, childId, 1, text);
+ }
+
+ // Iterate on Children until complete
+ int tokenDepth = vn.getTokenDepth(result);
+ int index = result + increment;
+ int childc = 1;
+ while(true){
+ index++;
+ int type = vn.getTokenType(index);
+ String s = vn.toString(index);
+ int d = vn.getTokenDepth(index);
+ // If type is element and depth is not greater than tokenDepth, break!
+ if((type == VTDNav.TOKEN_STARTING_TAG && d <=tokenDepth) || (type == VTDNav.TOKEN_STARTING_TAG && s.equals(""))){
+ break;
+ }
+ log.trace( " ... index: {} depth: {} type: {} string: {}", index, d, type, s);
+ index = transformFromXPath(vn, index, childc, childId, dataSourceId, properties, builder);
+ childc++;
+ }
+ return index - 1;
+ case VTDNav.TOKEN_ATTR_NAME:
+ // Attribute
+ String name = vn.toString(result);
+ String value = vn.toString(result + 1);
+ log.trace("Attribute {} = {}", name, value);
+ String attrChildId = String.join("", parentId , "/" , Integer.toString(child), ":", name);
+ builder.addContainer(dataSourceId, parentId, child, attrChildId);
+ builder.addValue(dataSourceId, attrChildId, name, value);
+ return result + 1;
+ case VTDNav.TOKEN_ATTR_VAL:
+ // Attribute value
+ log.trace("Attribute value: {}", vn.toString(result));
+ builder.addValue(dataSourceId, parentId, child, vn.toString(result));
+ break;
+ case VTDNav.TOKEN_CHARACTER_DATA:
+ // Text
+ String text = vn.toNormalizedString(result);
+ log.trace("Text: {}", text);
+ builder.addValue(dataSourceId, parentId, child, vn.toString(result));
+ break;
+ case VTDNav.TOKEN_DEC_ATTR_NAME:
+ log.trace("Attribute (dec): {} = {}", vn.toString(result), vn.toString(result + 1));
+ return result + 1;
+ case VTDNav.TOKEN_DEC_ATTR_VAL:
+ log.trace("Attribute value (dec) ", vn.toString(result));
+ break;
+ default:
+ log.warn("Ignored event: {} {}", vn.getTokenType(result), vn.toString(result));
+ }
+ return result;
+ }
+
+ public void transformSAX(Properties properties, FacadeXGraphBuilder builder) throws IOException, TriplifierHTTPException {
String namespace = Triplifier.getNamespaceArgument(properties);
String dataSourceId = Triplifier.getRootArgument(properties);
@@ -137,7 +265,7 @@ public void triplify(Properties properties, FacadeXGraphBuilder builder) throws
log.trace("element open: {} [{}]", path, stack.size());
// XXX Create an RDF resource
- String resourceId = path.substring(1);
+ String resourceId = StringUtils.join("", root, path);
// If this is the root
if (isRoot) {
// Add type root
@@ -203,4 +331,25 @@ public Set getMimeTypes() {
public Set getExtensions() {
return Sets.newHashSet("xml");
}
+
+
+ @Override
+ public void triplify(Properties properties, FacadeXGraphBuilder builder) throws IOException, TriplifierHTTPException {
+ List xpaths = Triplifier.getPropertyValues(properties, "xml.path");
+ if(!xpaths.isEmpty()){
+ transformWithXPath(xpaths, properties, builder);
+ }else{
+ transformSAX(properties, builder);
+ }
+ }
+
+ @Override
+ public Iterable slice(Properties p) throws IOException, TriplifierHTTPException {
+ return null;
+ }
+
+ @Override
+ public void triplify(Slice slice, Properties p, FacadeXGraphBuilder builder) {
+
+ }
}
diff --git a/sparql-anything-xml/src/test/java/com/github/sparqlanything/xml/MoreXMLTriplifierTest.java b/sparql-anything-xml/src/test/java/com/github/sparqlanything/xml/MoreXMLTriplifierTest.java
new file mode 100644
index 00000000..e0ea63e8
--- /dev/null
+++ b/sparql-anything-xml/src/test/java/com/github/sparqlanything/xml/MoreXMLTriplifierTest.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2022 SPARQL Anything Contributors @ http://github.com/sparql-anything
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.github.sparqlanything.xml;
+
+import com.github.sparqlanything.testutils.AbstractTriplifierTester;
+import org.apache.jena.riot.Lang;
+import org.apache.jena.riot.RDFDataMgr;
+import org.junit.Test;
+
+import java.util.Properties;
+
+public class MoreXMLTriplifierTest extends AbstractTriplifierTester {
+
+ public MoreXMLTriplifierTest() {
+ super(new XMLTriplifier(), new Properties(), "xml", "ttl");
+ }
+
+ @Override
+ protected void properties(Properties properties) {
+ if(name.getMethodName().equals("testSimple$1")){
+ properties.put("blank-nodes", "false");
+ }else
+ if(name.getMethodName().equals("testBooks$1")){
+ properties.put("blank-nodes", "false");
+ }else
+ if(name.getMethodName().equals("testBooks_1$1")){
+ properties.put("blank-nodes", "false");
+ properties.put("xml.path", "//book");
+ }
+ }
+
+ @Test
+ public void testSimple$1(){
+ //RDFDataMgr.write(System.err, result, Lang.TTL);
+ assertResultIsIsomorphicWithExpected();
+ }
+
+ @Test
+ public void testBooks$1(){
+// RDFDataMgr.write(System.err, result, Lang.TTL);
+ assertResultIsIsomorphicWithExpected();
+ }
+
+ @Test
+ public void testBooks_1$1(){
+ RDFDataMgr.write(System.err, result, Lang.TTL);
+ assertResultIsIsomorphicWithExpected();
+ }
+}
diff --git a/sparql-anything-xml/src/test/java/com/github/sparqlanything/xml/XMLTriplifierTest.java b/sparql-anything-xml/src/test/java/com/github/sparqlanything/xml/XMLTriplifierTest.java
index 9c7caa58..fd400d9f 100644
--- a/sparql-anything-xml/src/test/java/com/github/sparqlanything/xml/XMLTriplifierTest.java
+++ b/sparql-anything-xml/src/test/java/com/github/sparqlanything/xml/XMLTriplifierTest.java
@@ -36,7 +36,15 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import javax.xml.stream.XMLEventFactory;
+import javax.xml.stream.XMLEventReader;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
import java.io.IOException;
+import java.io.InputStream;
import java.net.URL;
import java.util.Iterator;
import java.util.Properties;
diff --git a/sparql-anything-xml/src/test/java/com/github/sparqlanything/xml/XPathSandbox.java b/sparql-anything-xml/src/test/java/com/github/sparqlanything/xml/XPathSandbox.java
new file mode 100644
index 00000000..18467979
--- /dev/null
+++ b/sparql-anything-xml/src/test/java/com/github/sparqlanything/xml/XPathSandbox.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 2022 SPARQL Anything Contributors @ http://github.com/sparql-anything
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.github.sparqlanything.xml;
+
+import com.ximpleware.AutoPilot;
+import com.ximpleware.VTDGen;
+import com.ximpleware.VTDNav;
+import org.apache.commons.io.IOUtils;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class XPathSandbox {
+
+ @Ignore
+ @Test
+ public void test() throws Exception {
+ printExprValue("/books/*");
+ printExprValue("//book");
+ printExprValue("//book[@isbn='978-3-12-148410-0']");
+ printExprValue("//book/@isbn");
+ printExprValue("//title/text()");
+ }
+
+ @Ignore
+ @Test
+ public void test2() throws Exception {
+ traverseMatches("//title");
+// printExprValue("/books/*");
+// printExprValue("//book");
+// printExprValue("//book[@isbn='978-3-12-148410-0']");
+// printExprValue("//book/@isbn");
+// printExprValue("//title/text()");
+ }
+
+ public void traverseMatches(String xpath) throws Exception{
+ System.out.println("Expression: " + xpath);
+ VTDGen vg = new VTDGen();
+ byte[] bytes = IOUtils.toByteArray(getClass().getClassLoader().getResourceAsStream("./test-xpaths.xml"));
+ vg.setDoc(bytes);
+ vg.parse(false);
+ VTDNav vn = vg.getNav();
+// vg.parse(false); // set namespace awareness to true
+ AutoPilot ap = new AutoPilot(vn);
+ //ap.declareXPathNameSpace("ns1","http://purl.org/dc/elements/1.1/");
+ ap.selectXPath(xpath);
+ int result = -1;
+ int count = 0;
+ while ((result = ap.evalXPath()) != -1) {
+ traverse(vn, result);
+ System.out.println(" *** ");
+ count++;
+ }
+ System.out.println("Total # of element " + count);
+ System.out.println("----------------------------");
+ }
+
+ private void printExprValue(String xpath) throws Exception{
+ System.out.println("Expression: " + xpath);
+ VTDGen vg = new VTDGen();
+ byte[] bytes = IOUtils.toByteArray(getClass().getClassLoader().getResourceAsStream("./test-xpaths.xml"));
+ vg.setDoc(bytes);
+ vg.parse(false);
+ VTDNav vn = vg.getNav();
+// vg.parse(false); // set namespace awareness to true
+ AutoPilot ap = new AutoPilot(vn);
+ //ap.declareXPathNameSpace("ns1","http://purl.org/dc/elements/1.1/");
+ ap.selectXPath(xpath);
+ int result = -1;
+ int count = 0;
+ while ((result = ap.evalXPath()) != -1) {
+ System.out.print("" + result + "[" + vn.getTokenType(result) + "] ");
+ switch(vn.getTokenType(result)){
+ case VTDNav.TOKEN_STARTING_TAG:
+ System.out.println("Tag "+vn.toString(result));
+ int nesting = vn.getNestingLevel();
+ // Attributes
+ int attrCount = vn.getAttrCount();
+ if (attrCount > 0) {
+ for (int i = result + 1; i <= result + attrCount; i += 2) {
+ System.out.println(" - Attr " + vn.toString(i) + " = " + vn.toString(i + 1));
+ }
+ }
+ // Print text
+ int t = vn.getText(); // get the index of the text (char data or CDATA)
+ if (t != -1)
+ System.out.println(" Text ==> " + vn.toNormalizedString(t));
+ break;
+ case VTDNav.TOKEN_ATTR_NAME:
+ // Attribute
+ System.out.println("Attribute " + vn.toString(result) );
+ System.out.println( " = " + vn.toString(result + 1));
+ break;
+ case VTDNav.TOKEN_ATTR_VAL:
+ // Attribute value
+ System.out.println("Attribute value" + vn.toString(result) );
+// System.out.println( " = " + vn.toString(result + 1));
+ break;
+ case VTDNav.TOKEN_CHARACTER_DATA:
+ // Text
+ System.out.println("Text");
+ System.out.println(" " + vn.toNormalizedString(result));
+ break;
+ case VTDNav.TOKEN_DEC_ATTR_NAME:
+ System.out.println("Attribute (dec) " + vn.toString(result) );
+ System.out.println( " = " + vn.toString(result + 1));
+ break;
+ case VTDNav.TOKEN_DEC_ATTR_VAL:
+ System.out.println("Attribute value (dec) " + vn.toString(result) );
+ break;
+ default:
+ System.out.println("????");
+ System.out.println(" ==> " + vn.toString(result));
+
+ }
+ count++;
+ }
+ System.out.println("Total # of element " + count);
+ System.out.println("----------------------------");
+ }
+
+ public void traverse(VTDNav nav, int index) throws Exception{
+ int tokenDepth = nav.getTokenDepth(index);
+ String tokenName = nav.toString(index);
+ // Leave out attributes
+ // Find child elements
+ while(true){
+ index++;
+// nav.toElement(index);
+ int type = nav.getTokenType(index);
+ String s = nav.toString(index);
+ int d = nav.getTokenDepth(index);
+ // If type is element and depth is not greater than tokenDepth, break!
+ if((type == VTDNav.TOKEN_STARTING_TAG && d <=tokenDepth) || (type == VTDNav.TOKEN_STARTING_TAG && s.equals(""))){
+ break;
+ }
+ System.out.println( " ... index: " + index + " depth: " + d + " type: " + type + " string: " + s);
+
+ }
+ }
+}
diff --git a/sparql-anything-xml/src/test/resources/Books.ttl b/sparql-anything-xml/src/test/resources/Books.ttl
new file mode 100644
index 00000000..560cb6c5
--- /dev/null
+++ b/sparql-anything-xml/src/test/resources/Books.ttl
@@ -0,0 +1,92 @@
+@prefix rdf: .
+@prefix rdfs: .
+@prefix fx: .
+@prefix xyz: .
+@prefix xsd: .
+
+
+ a xyz:price ;
+ rdf:_1 "5.95" .
+
+ a xyz:title ;
+ rdf:_1 "Midnight Rain" .
+
+ a xyz:price ;
+ rdf:_1 "44.95" .
+
+ a xyz:book ;
+ rdf:_1 ;
+ rdf:_2 ;
+ rdf:_3 ;
+ rdf:_4 ;
+ rdf:_5 ;
+ rdf:_6 ;
+ xyz:isbn "978-3-12-148410-0" .
+
+ a xyz:title ;
+ rdf:_1 "XML Developer's Guide" .
+
+ a xyz:books , ;
+ rdf:_1 ;
+ rdf:_2 ;
+ rdf:_3 .
+
+ a xyz:author ;
+ rdf:_1 "Ralls, Kim" .
+
+ a xyz:book ;
+ rdf:_1 ;
+ rdf:_2 ;
+ rdf:_3 ;
+ rdf:_4 ;
+ rdf:_5 ;
+ rdf:_6 ;
+ xyz:isbn "928-3-16-148410-0" .
+
+ a xyz:description ;
+ rdf:_1 "A former architect battles corporate zombies,\n an evil sorceress, and her own childhood to become queenof the world." .
+
+ a xyz:genre ;
+ rdf:_1 "Fantasy" .
+
+ a xyz:publish_date ;
+ rdf:_1 "2000-10-01" .
+
+ a xyz:author ;
+ rdf:_1 "Gambardella, Matthew" .
+
+ a xyz:description ;
+ rdf:_1 "An in-depth look at creating applications\n with XML." .
+
+ a xyz:genre ;
+ rdf:_1 "Fantasy" .
+
+ a xyz:book ;
+ rdf:_1 ;
+ rdf:_2 ;
+ rdf:_3 ;
+ rdf:_4 ;
+ rdf:_5 ;
+ rdf:_6 ;
+ xyz:isbn "432-3-16-143110-1" .
+
+ a xyz:price ;
+ rdf:_1 "5.95" .
+
+ a xyz:publish_date ;
+ rdf:_1 "2000-12-16" .
+
+ a xyz:genre ;
+ rdf:_1 "Computer" .
+
+ a xyz:author ;
+ rdf:_1 "Corets, Eva" .
+
+ a xyz:publish_date ;
+ rdf:_1 "2000-11-17" .
+
+ a xyz:title ;
+ rdf:_1 "Maeve Ascendant" .
+
+ a xyz:description ;
+ rdf:_1 "After the collapse of a nanotechnology\n society in England, the young survivors lay thefoundation for a new society." .
\ No newline at end of file
diff --git a/sparql-anything-xml/src/test/resources/Books.xml b/sparql-anything-xml/src/test/resources/Books.xml
new file mode 100644
index 00000000..2d48bc15
--- /dev/null
+++ b/sparql-anything-xml/src/test/resources/Books.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+ Gambardella, Matthew
+ XML Developer's Guide
+ Computer
+ 44.95
+ 2000-10-01
+ An in-depth look at creating applications
+ with XML.
+
+
+ Ralls, Kim
+ Midnight Rain
+ Fantasy
+ 5.95
+ 2000-12-16
+ A former architect battles corporate zombies,
+ an evil sorceress, and her own childhood to become queen
+ of the world.
+
+
+ Corets, Eva
+ Maeve Ascendant
+ Fantasy
+ 5.95
+ 2000-11-17
+ After the collapse of a nanotechnology
+ society in England, the young survivors lay the
+ foundation for a new society.
+
+
\ No newline at end of file
diff --git a/sparql-anything-xml/src/test/resources/Books_1.ttl b/sparql-anything-xml/src/test/resources/Books_1.ttl
new file mode 100644
index 00000000..38ec0654
--- /dev/null
+++ b/sparql-anything-xml/src/test/resources/Books_1.ttl
@@ -0,0 +1,135 @@
+@prefix rdf: .
+@prefix rdfs: .
+@prefix fx: .
+@prefix xyz: .
+@prefix xsd: .
+
+
+
+
+ "Fantasy" .
+
+
+
+ "A former architect battles corporate zombies,\n an evil sorceress, and her own childhood to become queen\n of the world." .
+
+
+
+ "Gambardella, Matthew" .
+
+
+ a ;
+
+ ;
+
+ ;
+
+ .
+
+
+
+ "Corets, Eva" .
+
+
+
+ "2000-10-01" .
+
+
+
+ "Fantasy" .
+
+
+
+ "2000-12-16" .
+
+
+
+ "5.95" .
+
+
+
+ "Computer" .
+
+
+
+ "Maeve Ascendant" .
+
+
+
+ ;
+
+ ;
+
+ ;
+
+ ;
+
+ ;
+
+ ;
+
+ "978-3-12-148410-0" .
+
+
+
+ "5.95" .
+
+
+
+ "An in-depth look at creating applications\n with XML." .
+
+
+
+ "2000-11-17" .
+
+
+
+ "Ralls, Kim" .
+
+
+
+ "Midnight Rain" .
+
+
+
+ "44.95" .
+
+
+
+ "XML Developer's Guide" .
+
+
+
+ "After the collapse of a nanotechnology\n society in England, the young survivors lay the\n foundation for a new society." .
+
+
+
+ ;
+
+ ;
+
+ ;
+
+ ;
+
+ ;
+
+ ;
+
+ "928-3-16-148410-0" .
+
+
+
+ ;
+
+ ;
+
+ ;
+
+ ;
+
+ ;
+
+ ;
+
+ "432-3-16-143110-1" .
\ No newline at end of file
diff --git a/sparql-anything-xml/src/test/resources/Books_1.xml b/sparql-anything-xml/src/test/resources/Books_1.xml
new file mode 100644
index 00000000..2d48bc15
--- /dev/null
+++ b/sparql-anything-xml/src/test/resources/Books_1.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+ Gambardella, Matthew
+ XML Developer's Guide
+ Computer
+ 44.95
+ 2000-10-01
+ An in-depth look at creating applications
+ with XML.
+
+
+ Ralls, Kim
+ Midnight Rain
+ Fantasy
+ 5.95
+ 2000-12-16
+ A former architect battles corporate zombies,
+ an evil sorceress, and her own childhood to become queen
+ of the world.
+
+
+ Corets, Eva
+ Maeve Ascendant
+ Fantasy
+ 5.95
+ 2000-11-17
+ After the collapse of a nanotechnology
+ society in England, the young survivors lay the
+ foundation for a new society.
+
+
\ No newline at end of file
diff --git a/sparql-anything-xml/src/test/resources/Simple.ttl b/sparql-anything-xml/src/test/resources/Simple.ttl
new file mode 100644
index 00000000..2c020642
--- /dev/null
+++ b/sparql-anything-xml/src/test/resources/Simple.ttl
@@ -0,0 +1,17 @@
+@prefix rdf: .
+@prefix rdfs: .
+@prefix fx: .
+@prefix xyz: .
+@prefix xsd: .
+
+
+ a , ;
+
+ .
+
+
+ a ;
+
+ "Some text here" ;
+
+ "food" .
\ No newline at end of file
diff --git a/sparql-anything-xml/src/test/resources/Simple.xml b/sparql-anything-xml/src/test/resources/Simple.xml
new file mode 100644
index 00000000..460ae3ce
--- /dev/null
+++ b/sparql-anything-xml/src/test/resources/Simple.xml
@@ -0,0 +1,3 @@
+
+ Some text here
+
\ No newline at end of file
diff --git a/sparql-anything-xml/src/test/resources/test-xpaths.xml b/sparql-anything-xml/src/test/resources/test-xpaths.xml
new file mode 100644
index 00000000..2d48bc15
--- /dev/null
+++ b/sparql-anything-xml/src/test/resources/test-xpaths.xml
@@ -0,0 +1,49 @@
+
+
+
+
+
+ Gambardella, Matthew
+ XML Developer's Guide
+ Computer
+ 44.95
+ 2000-10-01
+ An in-depth look at creating applications
+ with XML.
+
+
+ Ralls, Kim
+ Midnight Rain
+ Fantasy
+ 5.95
+ 2000-12-16
+ A former architect battles corporate zombies,
+ an evil sorceress, and her own childhood to become queen
+ of the world.
+
+
+ Corets, Eva
+ Maeve Ascendant
+ Fantasy
+ 5.95
+ 2000-11-17
+ After the collapse of a nanotechnology
+ society in England, the young survivors lay the
+ foundation for a new society.
+
+
\ No newline at end of file