├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── deploy.sh
├── jitpack.yml
├── pom.xml
├── spring-boot
├── xls2rdf-rest.zip
└── xls2rdf-rest
│ ├── .gitignore
│ ├── .mvn
│ └── wrapper
│ │ ├── MavenWrapperDownloader.java
│ │ ├── maven-wrapper.jar
│ │ └── maven-wrapper.properties
│ ├── mvnw
│ ├── mvnw.cmd
│ ├── pom.xml
│ └── src
│ ├── main
│ ├── java
│ │ └── fr
│ │ │ └── sparna
│ │ │ └── rdf
│ │ │ └── xls2rdf
│ │ │ └── rest
│ │ │ ├── ServletInitializer.java
│ │ │ └── Xls2rdfRestServiceApplication.java
│ └── resources
│ │ └── application.properties
│ └── test
│ └── java
│ └── fr
│ └── sparna
│ └── rdf
│ └── xls2rdf
│ └── rest
│ └── Xls2rdfRestServiceApplicationTests.java
├── xls2rdf-app
├── merge_output.xlsx
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── fr
│ │ │ └── sparna
│ │ │ └── rdf
│ │ │ └── xls2rdf
│ │ │ └── app
│ │ │ ├── ArgumentsConvert.java
│ │ │ ├── ArgumentsMain.java
│ │ │ ├── ArgumentsMerge.java
│ │ │ ├── CliCommandIfc.java
│ │ │ ├── Convert.java
│ │ │ ├── FileExistsValidator.java
│ │ │ ├── Main.java
│ │ │ └── Merge.java
│ └── resources
│ │ └── logback.xml
│ └── test
│ └── resources
│ ├── data.csv
│ └── header.xlsx
├── xls2rdf-lib
├── .gitignore
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── fr
│ │ │ └── sparna
│ │ │ └── rdf
│ │ │ └── xls2rdf
│ │ │ ├── ColumnHeader.java
│ │ │ ├── ColumnHeaderParser.java
│ │ │ ├── ExcelHelper.java
│ │ │ ├── ManchesterClassExpressionParser.java
│ │ │ ├── MergeCsvToXls.java
│ │ │ ├── ModelWriterIfc.java
│ │ │ ├── MyBidirectionalShortFormProvier.java
│ │ │ ├── MyOWLEntityChecker.java
│ │ │ ├── PrefixManager.java
│ │ │ ├── RdfizableSheet.java
│ │ │ ├── ResourceOrLiteralValueGenerator.java
│ │ │ ├── SKOSXL.java
│ │ │ ├── SparqlPathParser.java
│ │ │ ├── SparqlPropertyPathToShaclPropertyPathConverter.java
│ │ │ ├── TurtleParserTest.java
│ │ │ ├── ValueProcessorFactory.java
│ │ │ ├── ValueProcessorIfc.java
│ │ │ ├── Xls2RdfConverter.java
│ │ │ ├── Xls2RdfConverterFactory.java
│ │ │ ├── Xls2RdfException.java
│ │ │ ├── Xls2RdfMessageListenerIfc.java
│ │ │ ├── Xls2RdfPostProcessorIfc.java
│ │ │ ├── listen
│ │ │ ├── ListXls2RdfMessageListener.java
│ │ │ └── LogXls2RdfMessageListener.java
│ │ │ ├── postprocess
│ │ │ ├── AsListPostProcessor.java
│ │ │ ├── DynamicRdfTypePostProcessor.java
│ │ │ ├── OWLPostProcessor.java
│ │ │ ├── QBPostProcessor.java
│ │ │ ├── RdfTypePostProcessor.java
│ │ │ ├── RowHeaderLinkPostProcessor.java
│ │ │ ├── SkosPostProcessor.java
│ │ │ └── SkosXlPostProcessor.java
│ │ │ ├── reconcile
│ │ │ ├── DummyReconcileService.java
│ │ │ ├── DynamicReconciliableValueSet.java
│ │ │ ├── PreloadedReconciliableValueSet.java
│ │ │ ├── ReconcileMatchIfc.java
│ │ │ ├── ReconcileQueryIfc.java
│ │ │ ├── ReconcileResultIfc.java
│ │ │ ├── ReconcileServiceIfc.java
│ │ │ ├── ReconciliableValueSetIfc.java
│ │ │ ├── SimpleReconcileMatch.java
│ │ │ ├── SimpleReconcileQuery.java
│ │ │ ├── SimpleReconcileResult.java
│ │ │ └── SparqlReconcileService.java
│ │ │ └── write
│ │ │ ├── DirectoryModelWriter.java
│ │ │ ├── ModelWriterFactory.java
│ │ │ ├── OutputStreamModelWriter.java
│ │ │ ├── RDFHandlerFactory.java
│ │ │ ├── RepositoryModelWriter.java
│ │ │ └── ZipOutputStreamModelWriter.java
│ └── resources
│ │ ├── fr
│ │ └── sparna
│ │ │ └── rdf
│ │ │ └── xls2rdf
│ │ │ ├── postprocessing
│ │ │ └── broaderTransitive.ru
│ │ │ └── skos2skosxl
│ │ │ ├── S16-URIs.ru
│ │ │ ├── S16-bnodes.ru
│ │ │ ├── S55-S56-S57-URIs.ru
│ │ │ └── S55-S56-S57-bnodes.ru
│ │ └── logback-xls2rdf.xml
│ └── test
│ ├── java
│ └── fr
│ │ └── sparna
│ │ └── rdf
│ │ └── xls2rdf
│ │ ├── ColumnHeaderParserTest.java
│ │ ├── FormatsTest.java
│ │ ├── SimpleInvalidPropertyListValidator.java
│ │ ├── ValueProcessorTest.java
│ │ ├── Xls2RdfConverterTest.java
│ │ └── Xls2RdfConverterTestExecution.java
│ └── resources
│ └── suite
│ ├── .gitignore
│ ├── _00_simple
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xls
│ ├── _01_exemple1
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xlsx
│ ├── _02_prefixes
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xlsx
│ ├── _03_multilingual
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xlsx
│ ├── _04_datatypes_multiple_sheets
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xlsx
│ ├── _05_Collections_inverse
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xlsx
│ ├── _06_OrderedCollections_rdfLists
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xlsx
│ ├── _07_subjectColumn
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xlsx
│ ├── _08_lookupColumn
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xlsx
│ ├── _10_macro
│ ├── .gitignore
│ ├── expected.ttl
│ ├── input.xlsm
│ └── ~$input.xlsm
│ ├── _20_reconcileExternal
│ ├── .gitignore
│ ├── expected.ttl
│ ├── external.ttl
│ └── input.xls
│ ├── _21_reconcileLocal
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xls
│ ├── _22_reconcileOn
│ ├── .gitignore
│ ├── expected.ttl
│ ├── external.ttl
│ └── input.xls
│ ├── _23_rdfTypePostProcessing
│ ├── .gitignore
│ ├── expected.ttl
│ ├── external.ttl
│ └── input.xlsx
│ ├── _30_formatsTest
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xls
│ ├── _31_invalidPropertyTest
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xls
│ ├── _32_qbPostProcessingTest
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xlsx
│ ├── _33_vraiFaux
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xls
│ ├── _34_onlyHeader
│ ├── .gitignore
│ ├── expected.ttl
│ ├── input.xlsx
│ └── ~$input.xlsx
│ ├── _35_specialCharacters
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xlsx
│ ├── _36_mailto
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xlsx
│ ├── _37_ignoreIfParenthesis
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xls
│ ├── _38_hiddenRows
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xls
│ ├── _38_sharedPrefixes
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xls
│ ├── _40_ignoreIf
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xls
│ ├── _41_headerSeparator
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xlsx
│ ├── _42_xsddecimal
│ └── input.xlsx
│ ├── _43_cellPrecedence
│ ├── input.xlsx
│ └── output.ttl
│ ├── _44_blankNodes
│ └── input.xlsx
│ ├── _45_asList
│ ├── expected.ttl
│ └── input.xlsx
│ ├── _46_manchester
│ └── input.xlsx
│ ├── _47_copyTo
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xlsx
│ ├── _48_hiddenColumns
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xlsx
│ ├── _49_normalize-space
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xlsx
│ ├── _50_sparqlToShaclPath
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xlsx
│ ├── _51_base
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xlsx
│ ├── _52_wrapper
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xlsx
│ └── _53_zeroOrMorePath
│ ├── .gitignore
│ ├── expected.ttl
│ └── input.xlsx
└── xls2rdf-rest
├── pom.xml
├── src.bak
└── main
│ ├── java
│ └── fr
│ │ └── sparna
│ │ └── rdf
│ │ └── xls2rdf
│ │ └── rest
│ │ └── Xls2RdfRestApplication.java
│ └── resources
│ └── application.yml
└── src
├── main
├── java
│ └── fr
│ │ └── sparna
│ │ └── rdf
│ │ └── xls2rdf
│ │ └── rest
│ │ ├── ServletInitializer.java
│ │ ├── SimpleErrorController.java
│ │ ├── Xls2RdfRestController.java
│ │ ├── Xls2RdfService.java
│ │ └── Xls2rdfRestServiceApplication.java
├── resources
│ └── application.properties
└── webapp
│ ├── css
│ └── bootstrap.min.css
│ ├── doc.html
│ ├── images
│ ├── convert-screenshot-asList.png
│ ├── convert-screenshot-blankNode.png
│ ├── convert-screenshot-body.png
│ ├── convert-screenshot-collection.png
│ ├── convert-screenshot-datatype.png
│ ├── convert-screenshot-header.png
│ ├── convert-screenshot-lookupColumn.png
│ ├── convert-screenshot-manchester.png
│ ├── convert-screenshot-multilingual.png
│ ├── convert-screenshot-ordered-collection.png
│ ├── convert-screenshot-other-skos.png
│ ├── convert-screenshot-reconcileLocal.png
│ ├── convert-screenshot-shor.png
│ ├── convert-screenshot-subjectColumn.png
│ ├── convert-screenshot-title-row.png
│ ├── google-spreadsheet-url.png
│ ├── logo-luxembourg.png
│ └── sparna.png
│ └── index.html
└── test
└── java
└── fr
└── sparna
└── rdf
└── xls2rdf
└── rest
└── Xls2rdfRestServiceApplicationTests.java
/.gitignore:
--------------------------------------------------------------------------------
1 | .classpath
2 | .settings
3 | .project
4 | .settings/
5 | .svn/
6 | build/
7 | target/
8 | pom.xml.releaseBackup
9 |
10 | *.log
11 |
12 | xls2rdf-lib/src/test/resources/suite/_42_xsddecimal/output.ttl
13 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://travis-ci.org/sparna-git/xls2rdf)
2 |
3 | # xls2rdf
4 |
5 | Create RDF data by editing formatted Excel spreadsheets. We use this at Sparna to populate knowledge graphs with RDF instances, edit SKOS vocabularies, SHACL specifications, even OWL ontologies.
6 |
7 | ## Excel file structure
8 |
9 | Complete documentation of the expected Excel sheets format can be found at [https://xls2rdf.sparna.fr/rest/doc.html](https://xls2rdf.sparna.fr/rest/doc.html).
10 |
11 | ## Implementations
12 |
13 | ### xls2rdf REST API
14 |
15 | The Excel to RDF conversion service is accessible as an REST at http://xls2rdf.sparna.fr/rest/convert. It can work with online publicly accessible Google spreadsheets.
16 |
17 | ### xls2rdf upload form
18 |
19 | An upload form where you can upload your Excel file and download the result of the conversion is accessible in the SKOS Play application (for which this converter was historically designed) at https://skos-play.sparna.fr/play/convert
20 |
21 | ### xls2rdf on the command-line
22 |
23 | You can run the conversion from the command-line. See https://github.com/sparna-git/xls2rdf/wiki/Command-line-Excel-to-RDF-conversion
24 |
25 | ### xls2rdf Java API
26 |
27 | This is available as a Java jar library that can be integrated in your app.
28 |
29 | ## Example Excel files
30 |
31 | The upload form at https://skos-play.sparna.fr/play/convert contains downloable examples of Excel spreasheets.
32 |
33 | ## Generating templates from SHACL Application Profiles definition
34 |
35 | [@EmidioStani](https://github.com/EmidioStani) has contributed [shacl2spreadsheet](https://github.com/EmidioStani/shacl2spreadsheet), an Excel template generator based on a SHACL Application Profile definition
36 |
37 |
38 | ## rdf2xls
39 |
40 | See also https://github.com/sparna-git/rdf2xls which is the inverse tool : recreate Excel files from RDF data, based on a SHACL specification of the Excel file structure.
41 |
--------------------------------------------------------------------------------
/deploy.sh:
--------------------------------------------------------------------------------
1 |
2 | scp xls2rdf-rest/target/xls2rdf-rest-3.1.0.war admin@calliope.sparna.fr:xls2rdf-rest.war
3 |
4 | ssh -t admin@calliope.sparna.fr 'su -c "\
5 | rm -rf /var/lib/tomcat8/tomcat8-instance0/webapps/rest.war;\
6 | rm -rf /var/lib/tomcat8/tomcat8-instance0/webapps/rest;\
7 | service tomcat8-instance0 stop;\
8 | mv /home/admin/xls2rdf-rest.war /var/lib/tomcat8/tomcat8-instance0/webapps/rest.war;\
9 | service tomcat8-instance0 start;\
10 | "'
11 |
12 |
--------------------------------------------------------------------------------
/jitpack.yml:
--------------------------------------------------------------------------------
1 | jdk:
2 | - openjdk11
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 | fr.sparna.rdf.xls2rdf
6 | xls2rdf-pom
7 | 3.2.1
8 | pom
9 |
10 | XLS2RDF root POM
11 | All modules of XLS2RDF converter
12 | http://www.sparna.fr/
13 |
14 |
15 | Sparna
16 | http://labs.sparna.fr/skos-play/convert
17 |
18 |
19 |
20 | UTF-8
21 |
22 | 1.8
23 | 4.2.3
24 |
25 |
26 |
27 |
28 |
29 | org.apache.maven.plugins
30 | maven-compiler-plugin
31 | 3.8.1
32 |
33 | ${java.version}
34 | ${java.version}
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | org.slf4j
45 | slf4j-api
46 | 1.7.5
47 |
48 |
49 | org.slf4j
50 | slf4j-simple
51 | 1.7.5
52 |
53 |
54 | ch.qos.logback
55 | logback-classic
56 | 1.2.11
57 |
58 |
59 |
60 |
61 | junit
62 | junit
63 | 4.7
64 | test
65 |
66 |
67 |
68 |
69 | org.eclipse.rdf4j
70 | rdf4j-bom
71 | ${rdf4j.version}
72 | pom
73 | import
74 |
75 |
76 | org.eclipse.rdf4j
77 | rdf4j-rio-trix
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 | xls2rdf-lib
87 | xls2rdf-app
88 | xls2rdf-rest
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/spring-boot/xls2rdf-rest.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparna-git/xls2rdf/a7b6e173b300b8b4029b3eab93fb55689a2e849d/spring-boot/xls2rdf-rest.zip
--------------------------------------------------------------------------------
/spring-boot/xls2rdf-rest/.gitignore:
--------------------------------------------------------------------------------
1 | HELP.md
2 | target/
3 | !.mvn/wrapper/maven-wrapper.jar
4 | !**/src/main/**
5 | !**/src/test/**
6 |
7 | ### STS ###
8 | .apt_generated
9 | .classpath
10 | .factorypath
11 | .project
12 | .settings
13 | .springBeans
14 | .sts4-cache
15 |
16 | ### IntelliJ IDEA ###
17 | .idea
18 | *.iws
19 | *.iml
20 | *.ipr
21 |
22 | ### NetBeans ###
23 | /nbproject/private/
24 | /nbbuild/
25 | /dist/
26 | /nbdist/
27 | /.nb-gradle/
28 | build/
29 |
30 | ### VS Code ###
31 | .vscode/
32 |
--------------------------------------------------------------------------------
/spring-boot/xls2rdf-rest/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparna-git/xls2rdf/a7b6e173b300b8b4029b3eab93fb55689a2e849d/spring-boot/xls2rdf-rest/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/spring-boot/xls2rdf-rest/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
3 |
--------------------------------------------------------------------------------
/spring-boot/xls2rdf-rest/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.boot
7 | spring-boot-starter-parent
8 | 2.3.0.RELEASE
9 |
10 |
11 | fr.sparna.rdf.xls2rdf
12 | xls2rdf-rest
13 | 0.0.1-SNAPSHOT
14 | war
15 | xls2rdf REST service
16 | REST service for xls2rdf
17 |
18 |
19 | 11
20 |
21 |
22 |
23 |
24 | org.springframework.boot
25 | spring-boot-starter-web
26 |
27 |
28 |
29 | org.springframework.boot
30 | spring-boot-starter-tomcat
31 | provided
32 |
33 |
34 | org.springframework.boot
35 | spring-boot-starter-test
36 | test
37 |
38 |
39 | org.junit.vintage
40 | junit-vintage-engine
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | org.springframework.boot
50 | spring-boot-maven-plugin
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/spring-boot/xls2rdf-rest/src/main/java/fr/sparna/rdf/xls2rdf/rest/ServletInitializer.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.rest;
2 |
3 | import org.springframework.boot.builder.SpringApplicationBuilder;
4 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
5 |
6 | public class ServletInitializer extends SpringBootServletInitializer {
7 |
8 | @Override
9 | protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
10 | return application.sources(Xls2rdfRestServiceApplication.class);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/spring-boot/xls2rdf-rest/src/main/java/fr/sparna/rdf/xls2rdf/rest/Xls2rdfRestServiceApplication.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.rest;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class Xls2rdfRestServiceApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(Xls2rdfRestServiceApplication.class, args);
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/spring-boot/xls2rdf-rest/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/spring-boot/xls2rdf-rest/src/test/java/fr/sparna/rdf/xls2rdf/rest/Xls2rdfRestServiceApplicationTests.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.rest;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class Xls2rdfRestServiceApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/xls2rdf-app/merge_output.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparna-git/xls2rdf/a7b6e173b300b8b4029b3eab93fb55689a2e849d/xls2rdf-app/merge_output.xlsx
--------------------------------------------------------------------------------
/xls2rdf-app/src/main/java/fr/sparna/rdf/xls2rdf/app/ArgumentsMain.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.app;
2 |
3 | import java.io.File;
4 |
5 | import com.beust.jcommander.Parameter;
6 | import com.beust.jcommander.converters.FileConverter;
7 |
8 | public class ArgumentsMain {
9 |
10 | @Parameter(
11 | names = { "-h", "--help" },
12 | description = "Prints the help message",
13 | help = true
14 | )
15 | private boolean help = false;
16 |
17 | @Parameter(
18 | names = { "-l", "--log" },
19 | description = "Reference to a log4j configuration file",
20 | converter = FileConverter.class
21 | )
22 | private File log;
23 |
24 | public boolean isHelp() {
25 | return help;
26 | }
27 |
28 | public void setHelp(boolean help) {
29 | this.help = help;
30 | }
31 |
32 | public File getLog() {
33 | return log;
34 | }
35 |
36 | public void setLog(File log) {
37 | this.log = log;
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/xls2rdf-app/src/main/java/fr/sparna/rdf/xls2rdf/app/ArgumentsMerge.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.app;
2 |
3 | import com.beust.jcommander.Parameter;
4 | import com.beust.jcommander.Parameters;
5 | import com.beust.jcommander.converters.FileConverter;
6 |
7 | import java.io.File;
8 |
9 | @Parameters(commandDescription = "Merge an input CSV file into an Excel file that declares the header and columns to be converted to RDF.")
10 | public class ArgumentsMerge {
11 |
12 | @Parameter(
13 | names = { "-e", "--excel" },
14 | description = "Excel file containing the header and column definitions, in which the CSV file will be merged.",
15 | converter = FileConverter.class,
16 | validateWith = FileExistsValidator.class,
17 | required = true
18 | )
19 | private File excel;
20 |
21 | @Parameter(
22 | names = { "-o", "--output" },
23 | description = "Output Excel file",
24 | converter = FileConverter.class,
25 | required = true
26 | )
27 | private File output;
28 |
29 | @Parameter(
30 | names = { "-c", "--csv" },
31 | description = "Input csv file",
32 | converter = FileConverter.class,
33 | validateWith = FileExistsValidator.class,
34 | required = false
35 | )
36 | private File csv;
37 |
38 |
39 | public File getCsv() {
40 | return csv;
41 | }
42 |
43 | public void setCsv(File csv) {
44 | this.csv = csv;
45 | }
46 |
47 | public File getExcel() {
48 | return excel;
49 | }
50 |
51 | public void setExcel(File excel) {
52 | this.excel = excel;
53 | }
54 |
55 | public File getOutput() {
56 | return output;
57 | }
58 |
59 | public void setOutput(File output) {
60 | this.output = output;
61 | }
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/xls2rdf-app/src/main/java/fr/sparna/rdf/xls2rdf/app/CliCommandIfc.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.app;
2 |
3 |
4 | public interface CliCommandIfc {
5 |
6 | public void execute(Object args) throws Exception;
7 |
8 | }
9 |
--------------------------------------------------------------------------------
/xls2rdf-app/src/main/java/fr/sparna/rdf/xls2rdf/app/FileExistsValidator.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.app;
2 |
3 | import java.io.File;
4 |
5 | import com.beust.jcommander.IParameterValidator;
6 | import com.beust.jcommander.ParameterException;
7 | import com.beust.jcommander.converters.FileConverter;
8 |
9 | /**
10 | * A validator that makes sure the value of the parameter is a file
11 | * that exists on the filesystem.
12 | *
13 | * @author Matthew Kirkley
14 | */
15 | public class FileExistsValidator implements IParameterValidator {
16 |
17 | @Override
18 | public void validate(String name, String value) throws ParameterException {
19 | File file = getFile(value);
20 | if (!file.exists()) {
21 | throw new ParameterException("Parameter " + name + " which should represent a file that exists, does not exist.");
22 | }
23 | }
24 |
25 | File getFile(String value) {
26 | return new FileConverter().convert(value);
27 | }
28 |
29 | }
--------------------------------------------------------------------------------
/xls2rdf-app/src/main/java/fr/sparna/rdf/xls2rdf/app/Main.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.app;
2 |
3 | import com.beust.jcommander.JCommander;
4 | import com.beust.jcommander.MissingCommandException;
5 | import com.beust.jcommander.ParameterException;
6 |
7 | public class Main {
8 |
9 | enum COMMAND {
10 |
11 | CONVERT(new ArgumentsConvert(), new Convert()),
12 | MERGE(new ArgumentsMerge(), new Merge()),
13 | ;
14 |
15 | private CliCommandIfc command;
16 | private Object arguments;
17 |
18 | private COMMAND(Object arguments, CliCommandIfc command) {
19 | this.command = command;
20 | this.arguments = arguments;
21 | }
22 |
23 | public CliCommandIfc getCommand() {
24 | return command;
25 | }
26 |
27 | public Object getArguments() {
28 | return arguments;
29 | }
30 | }
31 |
32 | private void run(String[] args) throws Exception {
33 | ArgumentsMain main = new ArgumentsMain();
34 | JCommander jc = new JCommander(main);
35 |
36 | for (COMMAND aCOMMAND : COMMAND.values()) {
37 | jc.addCommand(aCOMMAND.name().toLowerCase(), aCOMMAND.getArguments());
38 | }
39 |
40 | try {
41 | jc.parse(args);
42 | // a mettre avant ParameterException car c'est une sous-exception
43 | } catch (MissingCommandException e) {
44 | // if no command was found, exit with usage message and error code
45 | System.err.println("Unkwown command.");
46 | jc.usage();
47 | System.exit(-1);
48 | } catch (ParameterException e) {
49 | System.err.println(e.getMessage());
50 | jc.usage(jc.getParsedCommand());
51 | System.exit(-1);
52 | }
53 |
54 | // if help was requested, print it and exit with a normal code
55 | if(main.isHelp()) {
56 | jc.usage();
57 | System.exit(0);
58 | }
59 |
60 | // if no command was found (0 parameters passed in command line)
61 | // exit with usage message and error code
62 | if(jc.getParsedCommand() == null) {
63 | System.err.println("No command found.");
64 | jc.usage();
65 | System.exit(-1);
66 | }
67 |
68 | // configure logging using log4j
69 | // if(main.getLog() != null) {
70 | // if(main.getLog().getName().endsWith(".xml")) {
71 | // DOMConfigurator.configure(main.getLog().getAbsolutePath());
72 | // } else {
73 | // PropertyConfigurator.configure(main.getLog().getAbsolutePath());
74 | // }
75 | // } else {
76 | // DOMConfigurator.configure(ClassLoader.getSystemResource("log4j.xml"));
77 | // }
78 |
79 | // executes the command with the associated arguments
80 | COMMAND.valueOf(jc.getParsedCommand().toUpperCase()).getCommand().execute(
81 | COMMAND.valueOf(jc.getParsedCommand().toUpperCase()).getArguments()
82 | );
83 | }
84 |
85 | public static void main(String[] args) throws Exception {
86 | Main me = new Main();
87 | me.run(args);
88 | }
89 |
90 |
91 | }
92 |
--------------------------------------------------------------------------------
/xls2rdf-app/src/main/java/fr/sparna/rdf/xls2rdf/app/Merge.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.app;
2 |
3 | import java.io.FileInputStream;
4 | import java.io.FileOutputStream;
5 | import java.io.InputStream;
6 | import java.io.InputStreamReader;
7 | import java.io.OutputStream;
8 | import java.util.List;
9 |
10 | import org.apache.commons.csv.CSVFormat;
11 | import org.apache.commons.csv.CSVParser;
12 | import org.apache.commons.csv.CSVRecord;
13 | import org.apache.commons.io.FileUtils;
14 | import org.apache.poi.ss.usermodel.Workbook;
15 | import org.apache.poi.ss.usermodel.WorkbookFactory;
16 | import org.slf4j.Logger;
17 | import org.slf4j.LoggerFactory;
18 |
19 | import fr.sparna.rdf.xls2rdf.MergeCsvToXls;
20 |
21 | public class Merge implements CliCommandIfc {
22 |
23 | private Logger log = LoggerFactory.getLogger(this.getClass().getName());
24 |
25 | @Override
26 | public void execute(Object args) throws Exception {
27 | ArgumentsMerge a = (ArgumentsMerge)args;
28 |
29 | // Copy file output from excel
30 | FileUtils.copyFile(a.getExcel(), a.getOutput());
31 | // Create workbook instance
32 | Workbook workbookXSL = WorkbookFactory.create(a.getOutput());
33 |
34 | // Parser csv File
35 | InputStream inFile = new FileInputStream(a.getCsv());
36 | CSVParser csvParser = new CSVParser(
37 | new InputStreamReader(inFile),
38 | CSVFormat.DEFAULT.builder()
39 | .setDelimiter(";")
40 | .setSkipHeaderRecord(true)
41 | .build()
42 | );
43 | // get Records values
44 | List cvsRecords = csvParser.getRecords();
45 |
46 | MergeCsvToXls merger = new MergeCsvToXls();
47 | Workbook wb = merger.mergeCsv(cvsRecords, workbookXSL);
48 | if (wb != null) {
49 |
50 | // Delete output file ????????
51 | if (a.getOutput().exists()) {
52 | a.getOutput().delete();
53 | }
54 |
55 | try (OutputStream outputFile = new FileOutputStream(a.getOutput())) {
56 | wb.write(outputFile);
57 | log.debug("Successfully wrote Excel file in " + a.getOutput().getAbsolutePath());
58 | } catch (Exception e) {
59 | // TODO: handle exception
60 |
61 | }
62 | }
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/xls2rdf-app/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | %d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n
7 |
8 |
9 |
10 |
11 | xls2rdf.log
12 |
13 |
14 | xls2rdf.%d{yyyy-MM-dd}.log
15 |
16 |
17 | 5
18 |
19 |
20 | %d{HH:mm:ss.SSS} %-4relative %-5level %logger{35} - %msg%n
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/xls2rdf-app/src/test/resources/data.csv:
--------------------------------------------------------------------------------
1 | URI;rdf:type;sh:targetClass;rdfs:comment@en;skos:example^^xsd:string;sh:nodeKind;sh:pattern^^xsd:string;sh:closed^^xsd:boolean;sh:ignoredProperties;rdfs:label@fr;rdfs:label@en;sh:description^^xsd:string;sh:order^^xsd:integer;skos:editorialNote@en;owl:versionInfo;shacl-play:color
2 | https://shacl-play.sparna.fr/shapes/Activity;sh:NodeShape;eli-dl:Activity;;;;;;;;Activity;;;;;
3 | https://shacl-play.sparna.fr/shapes/Expression;sh:NodeShape;eli:Expression;;;;;;;;Expression;;;;;
4 | https://shacl-play.sparna.fr/shapes/Manifestation;sh:NodeShape;eli:Manifestation;;;;;;;;Manifestation;;;;;
5 | https://shacl-play.sparna.fr/shapes/Work;sh:NodeShape;eli:Work;;;;;;;;Work;;;;;
6 | https://shacl-play.sparna.fr/shapes/WorkSubdivision;sh:NodeShape;eli-dl:WorkSubdivision;;;;;;;;WorkSubdivision;;;;;
7 |
--------------------------------------------------------------------------------
/xls2rdf-app/src/test/resources/header.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparna-git/xls2rdf/a7b6e173b300b8b4029b3eab93fb55689a2e849d/xls2rdf-app/src/test/resources/header.xlsx
--------------------------------------------------------------------------------
/xls2rdf-lib/.gitignore:
--------------------------------------------------------------------------------
1 | /xls2rdf.log
2 |
--------------------------------------------------------------------------------
/xls2rdf-lib/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 |
5 |
6 | fr.sparna.rdf.xls2rdf
7 | xls2rdf-pom
8 | 3.2.1
9 | ../pom.xml
10 |
11 |
12 | xls2rdf-lib
13 |
14 |
15 | Excel2RDF Library
16 | Turns Excel files from specific templates into RDF and SKOS
17 |
18 |
19 | Sparna
20 | http://www.sparna.fr/
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 | org.slf4j
32 | slf4j-api
33 |
34 |
35 | ch.qos.logback
36 | logback-classic
37 |
38 |
39 |
40 | junit
41 | junit
42 |
43 |
44 |
45 | org.eclipse.rdf4j
46 | rdf4j-storage
47 | pom
48 |
49 |
50 |
51 | org.apache.poi
52 | poi
53 | 5.2.3
54 |
55 |
56 |
57 | org.apache.poi
58 | poi-ooxml
59 | 5.2.3
60 |
61 |
62 |
63 | net.sourceforge.owlapi
64 | owlapi-distribution
65 | 5.5.0
66 |
67 |
68 |
69 |
70 | org.apache.commons
71 | commons-csv
72 | 1.10.0
73 |
74 |
75 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/ExcelHelper.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Calendar;
5 | import java.util.List;
6 | import java.util.TimeZone;
7 | import java.util.stream.Collectors;
8 |
9 | import org.apache.poi.ss.usermodel.Cell;
10 | import org.apache.poi.ss.usermodel.CellType;
11 | import org.apache.poi.ss.usermodel.DateUtil;
12 | import org.apache.poi.ss.usermodel.Row;
13 | import org.apache.poi.ss.usermodel.Sheet;
14 | import org.apache.poi.ss.util.CellReference;
15 | import org.slf4j.Logger;
16 | import org.slf4j.LoggerFactory;
17 |
18 | public class ExcelHelper {
19 |
20 | private static Logger log = LoggerFactory.getLogger(ExcelHelper.class.getName());
21 |
22 | private ExcelHelper() {
23 | }
24 |
25 | public static String getCellValue(Cell cell) {
26 | if(cell == null) return null;
27 | return getCellValue(cell.getCellType(), cell);
28 | }
29 |
30 | private static String getCellValue(CellType type, Cell cell) {
31 | // blank or error cells give an empty value
32 | if (type == CellType.BLANK || type == CellType.ERROR) {
33 | return "";
34 | } else if (type == CellType.STRING) {
35 | return cell.getStringCellValue().trim();
36 | } else if (type == CellType.NUMERIC) {
37 | double d = cell.getNumericCellValue();
38 | if((d % 1) == 0) {
39 | // return it as an int without the dot to avoid values like "1.0"
40 | return "" + new Double(d).intValue();
41 | } else {
42 | return "" + d;
43 | }
44 | } else if (type == CellType.BOOLEAN) {
45 | return Boolean.toString(cell.getBooleanCellValue());
46 | } else if (type == CellType.FORMULA) {
47 | // Re-run based on the formula type
48 | return getCellValue(cell.getCachedFormulaResultType(), cell);
49 | } else {
50 | throw new Xls2RdfException("Cell type unknown or unsupported ({}) at Sheet '{}', row {}, column {}", type.name(), cell.getSheet().getSheetName(), cell.getRowIndex(), cell.getColumnIndex());
51 | }
52 | }
53 |
54 |
55 | public static Calendar asCalendar(String value) {
56 | Calendar calendar = DateUtil.getJavaCalendar(Double.valueOf(value));
57 | calendar.setTimeZone(TimeZone.getTimeZone("CEST"));
58 | return calendar;
59 | }
60 |
61 | public static Row columnLookup(String value, Sheet sheet, int columnIndex, boolean ignoreCase) {
62 | List foundRows = new ArrayList<>();
63 | for(Row r : sheet) {
64 | Cell c = r.getCell(columnIndex);
65 | if(c != null) {
66 | String cellValue = getCellValue(c);
67 | if(
68 | (!ignoreCase && cellValue.trim().equals(value.trim()))
69 | ||
70 | (ignoreCase && cellValue.trim().equalsIgnoreCase(value.trim()))
71 | ) {
72 | foundRows.add(r);
73 | }
74 | }
75 | }
76 |
77 | if(foundRows.size() == 0) {
78 | // not found
79 | return null;
80 | } else if(foundRows.size() > 1) {
81 | // found multiple times
82 | String references = foundRows.stream().map(r -> new CellReference(r.getRowNum(), columnIndex).formatAsString()).collect(Collectors.joining(" "));
83 | throw new Xls2RdfException("Ambiguous reference : found value '"+value+"' "+foundRows.size()+" times ("+references+"). Fix the values to garantee they are unique.");
84 | } else {
85 | // single value
86 | return foundRows.get(0);
87 | }
88 |
89 |
90 | }
91 |
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/MergeCsvToXls.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf;
2 |
3 | import java.io.IOException;
4 | import java.util.List;
5 |
6 | import org.apache.commons.csv.CSVRecord;
7 | import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
8 | import org.apache.poi.ss.usermodel.Cell;
9 | import org.apache.poi.ss.usermodel.Row;
10 | import org.apache.poi.ss.usermodel.Sheet;
11 | import org.apache.poi.ss.usermodel.Workbook;
12 | import org.slf4j.Logger;
13 | import org.slf4j.LoggerFactory;
14 |
15 |
16 | public class MergeCsvToXls {
17 |
18 | static Logger log = LoggerFactory.getLogger(RdfizableSheet.class.getName());
19 |
20 | public Workbook mergeCsv(List csvRecords, Workbook workbookXLS) throws InvalidFormatException, IOException {
21 |
22 | // Get all prefix
23 | PrefixManager prefixManager = getPrefixes(workbookXLS);
24 | int indexSheet = this.getMergeSheetIndex(workbookXLS , prefixManager);
25 |
26 | // TODO : test if indexSheet < 0
27 | if (indexSheet == -1) {
28 | log.debug("Warning: Not found a sheetstyle in the document....");
29 | return null;
30 | } else {
31 | Sheet targetSheet = workbookXLS.getSheetAt(indexSheet);
32 | int rowIndexTitle = new RdfizableSheet(targetSheet, prefixManager).computeTitleRowIndex();
33 | int nRow = rowIndexTitle;
34 |
35 | // get all data values
36 | for (int i = 1; i < csvRecords.size(); i++) {
37 | CSVRecord r = csvRecords.get(i);
38 | nRow++;
39 | // create row in the sheet
40 | Row newRow = targetSheet.createRow(nRow);
41 | for (int j = 0; j < r.values().length; j++) {
42 | Cell newCell = newRow.createCell(j);
43 | // write in column
44 | String value = r.get(j);
45 | newCell.setCellValue(value);
46 | }
47 | }
48 | return workbookXLS;
49 | }
50 | }
51 |
52 | public PrefixManager getPrefixes(Workbook workbook) throws InvalidFormatException, IOException {
53 | // Start instance
54 | PrefixManager prefixManager = new PrefixManager();
55 | // register prefixes
56 | for (Sheet sheet : workbook) {
57 | prefixManager.register(RdfizableSheet.readPrefixes(sheet));
58 | }
59 |
60 | return prefixManager;
61 | }
62 |
63 | public Integer getMergeSheetIndex(Workbook wbInput, PrefixManager prefixManager) throws InvalidFormatException, IOException {
64 | // find the target sheet
65 | for (Sheet sheet : wbInput) {
66 | RdfizableSheet rdfizableSheetActive = new RdfizableSheet(sheet, prefixManager);
67 | if (rdfizableSheetActive.canRDFize()) {
68 | return wbInput.getSheetIndex(sheet.getSheetName());
69 | }
70 | }
71 | // return -1 if not found
72 | return -1;
73 | }
74 |
75 | }
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/ModelWriterIfc.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf;
2 |
3 | import java.util.Map;
4 |
5 | import org.eclipse.rdf4j.model.Model;
6 |
7 | public interface ModelWriterIfc {
8 |
9 | public void beginWorkbook();
10 |
11 | public void saveGraphModel(String graph, Model model, Map prefixes, String baseIri);
12 |
13 | public void endWorkbook();
14 |
15 |
16 | }
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/MyBidirectionalShortFormProvier.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf;
2 |
3 | import java.util.Collections;
4 | import java.util.stream.Stream;
5 |
6 | import org.semanticweb.owlapi.model.OWLDataFactory;
7 | import org.semanticweb.owlapi.model.OWLEntity;
8 | import org.semanticweb.owlapi.util.BidirectionalShortFormProvider;
9 | import org.semanticweb.owlapi.util.SimpleShortFormProvider;
10 |
11 | public class MyBidirectionalShortFormProvier implements BidirectionalShortFormProvider {
12 |
13 | protected String defaultNamespace;
14 | protected OWLDataFactory df;
15 |
16 |
17 | public MyBidirectionalShortFormProvier() {
18 | super();
19 | }
20 |
21 | @Override
22 | public String getShortForm(OWLEntity entity) {
23 | return new SimpleShortFormProvider().getShortForm(entity);
24 | }
25 |
26 | @Override
27 | public Stream entities(String shortForm) {
28 | return Collections.singletonList(this.getEntity(shortForm)).stream();
29 | }
30 |
31 | @Override
32 | public OWLEntity getEntity(String shortForm) {
33 | // if short form starts with capital letter
34 | if(Character.isUpperCase(shortForm.charAt(0))) {
35 | // then it is a class
36 | return df.getOWLClass(this.defaultNamespace+shortForm);
37 | } else {
38 | // otherwise consider it an ObjectProperty
39 | return df.getOWLObjectProperty(this.defaultNamespace+shortForm);
40 | }
41 | }
42 |
43 | @Override
44 | public Stream shortForms() {
45 | return null;
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/MyOWLEntityChecker.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf;
2 |
3 | import org.semanticweb.owlapi.expression.OWLEntityChecker;
4 | import org.semanticweb.owlapi.model.OWLAnnotationProperty;
5 | import org.semanticweb.owlapi.model.OWLClass;
6 | import org.semanticweb.owlapi.model.OWLDataFactory;
7 | import org.semanticweb.owlapi.model.OWLDataProperty;
8 | import org.semanticweb.owlapi.model.OWLDatatype;
9 | import org.semanticweb.owlapi.model.OWLNamedIndividual;
10 | import org.semanticweb.owlapi.model.OWLObjectProperty;
11 |
12 | import ch.qos.logback.core.recovery.ResilientSyslogOutputStream;
13 |
14 | public class MyOWLEntityChecker implements OWLEntityChecker {
15 |
16 | private static final String DATATYPE_NAME_MARKER = "literal_";
17 | protected OWLDataFactory df;
18 | protected PrefixManager prefixManager;
19 |
20 |
21 | public MyOWLEntityChecker(PrefixManager prefixManager, OWLDataFactory df) {
22 | super();
23 | this.prefixManager = prefixManager;
24 | this.df = df;
25 | }
26 |
27 | @Override
28 | public OWLClass getOWLClass(String token) {
29 | if(!isName(token)) {
30 | return null;
31 | }
32 |
33 | if(token.startsWith("xsd")) {
34 | return null;
35 | }
36 |
37 | if(token.contains(DATATYPE_NAME_MARKER)) {
38 | return null;
39 | }
40 |
41 | return df.getOWLClass(this.prefixManager.expand(token));
42 | }
43 |
44 | @Override
45 | public OWLObjectProperty getOWLObjectProperty(String token) {
46 | if(!isName(token)) {
47 | return null;
48 | }
49 |
50 | if(token.startsWith("xsd")) {
51 | return null;
52 | }
53 |
54 | if(token.contains(DATATYPE_NAME_MARKER)) {
55 | return null;
56 | }
57 |
58 | return df.getOWLObjectProperty(this.prefixManager.expand(token));
59 | }
60 |
61 | @Override
62 | public OWLDataProperty getOWLDataProperty(String token) {
63 | if(!isName(token)) {
64 | return null;
65 | }
66 |
67 | return df.getOWLDataProperty(this.prefixManager.expand(token));
68 | }
69 |
70 | @Override
71 | public OWLNamedIndividual getOWLIndividual(String token) {
72 | if(!isName(token)) {
73 | return null;
74 | }
75 |
76 | return df.getOWLNamedIndividual(this.prefixManager.expand(token));
77 | }
78 |
79 | @Override
80 | public OWLDatatype getOWLDatatype(String token) {
81 | if(!isName(token)) {
82 | return null;
83 | }
84 |
85 | return df.getOWLDatatype(this.prefixManager.expand(token));
86 | }
87 |
88 | @Override
89 | public OWLAnnotationProperty getOWLAnnotationProperty(String token) {
90 | if(!isName(token)) {
91 | return null;
92 | }
93 |
94 | return df.getOWLAnnotationProperty(this.prefixManager.expand(token));
95 | }
96 |
97 | private boolean isName(String token) {
98 | return !(token.equals("(") || token.equals(")"));
99 | }
100 |
101 | }
102 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/SKOSXL.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf;
2 |
3 | import org.eclipse.rdf4j.model.IRI;
4 | import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
5 |
6 | public class SKOSXL {
7 | public static String NAMESPACE = "http://www.w3.org/2008/05/skos-xl#";
8 | public static IRI PREF_LABEL = SimpleValueFactory.getInstance().createIRI(NAMESPACE+"prefLabel");
9 | public static IRI ALT_LABEL = SimpleValueFactory.getInstance().createIRI(NAMESPACE+"altLabel");
10 | public static IRI HIDDEN_LABEL = SimpleValueFactory.getInstance().createIRI(NAMESPACE+"hiddenLabel");
11 | public static IRI LABEL = SimpleValueFactory.getInstance().createIRI(NAMESPACE+"Label");
12 | public static IRI LITERAL_FORM = SimpleValueFactory.getInstance().createIRI(NAMESPACE+"literalForm");
13 | }
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/SparqlPathParser.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf;
2 |
3 | import java.util.List;
4 | import org.apache.commons.lang3.StringUtils;
5 | import org.apache.poi.ss.usermodel.Cell;
6 | import org.eclipse.rdf4j.model.Model;
7 | import org.eclipse.rdf4j.model.Resource;
8 | import org.eclipse.rdf4j.model.Statement;
9 | import org.eclipse.rdf4j.query.parser.sparql.ast.ParseException;
10 | import org.eclipse.rdf4j.query.parser.sparql.ast.TokenMgrError;
11 | import org.slf4j.Logger;
12 | import org.slf4j.LoggerFactory;
13 |
14 | public class SparqlPathParser implements ValueProcessorIfc {
15 |
16 | private Logger log = LoggerFactory.getLogger(this.getClass().getName());
17 |
18 | /**
19 | *
20 | */
21 | protected ColumnHeader header;
22 | protected PrefixManager prefixManager;
23 | protected Xls2RdfMessageListenerIfc messageListener;
24 | protected ValueProcessorIfc delegateProcessor;
25 |
26 | public SparqlPathParser(ValueProcessorIfc delegate, ColumnHeader header, PrefixManager prefixManager, Xls2RdfMessageListenerIfc messageListener) {
27 | super();
28 | this.delegateProcessor = delegate;
29 | this.header = header;
30 | this.prefixManager = prefixManager;
31 | this.messageListener = messageListener;
32 | }
33 |
34 | @Override
35 | public List processValue(Model model, Resource subject, String value, Cell cell, String language) {
36 | if (StringUtils.isBlank(ValueProcessorFactory.normalizeSpace(value))) {
37 | return null;
38 | }
39 |
40 | log.debug("Parsing a SPARQL property path : '"+value+"'");
41 |
42 | try {
43 | SparqlPropertyPathToShaclPropertyPathConverter converter = new SparqlPropertyPathToShaclPropertyPathConverter(this.prefixManager);
44 | String shaclPath = converter.convertToShaclPropertyPath(ValueProcessorFactory.normalizeSpace(value));
45 | return this.delegateProcessor.processValue(model, subject, shaclPath, cell, language);
46 | } catch (TokenMgrError | ParseException e) {
47 | // will default to a normal parsing
48 | this.delegateProcessor.processValue(model, subject, value, cell, language);
49 | return null;
50 | }
51 | };
52 |
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/TurtleParserTest.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf;
2 |
3 | import java.io.StringReader;
4 |
5 | import org.eclipse.rdf4j.model.vocabulary.RDF;
6 | import org.eclipse.rdf4j.rio.RDFFormat;
7 | import org.eclipse.rdf4j.rio.RDFParser;
8 | import org.eclipse.rdf4j.rio.RDFParserRegistry;
9 | import org.eclipse.rdf4j.rio.helpers.StatementCollector;
10 |
11 | public class TurtleParserTest {
12 |
13 | public static void main(String... strings) {
14 | // try to parse it like a blank node
15 | StringBuffer turtle = new StringBuffer();
16 | turtle.append("@prefix sh: ."+"\n");
17 | turtle.append("@prefix eli: ."+"\n");
18 | turtle.append(" [ sh:inversePath eli:is_realized_by] .");
19 | System.out.println(turtle.toString());
20 | StatementCollector collector = new StatementCollector();
21 | RDFParser parser = RDFParserRegistry.getInstance().get(RDFFormat.TURTLE).get().getParser();
22 | parser.setRDFHandler(collector);
23 | try {
24 | parser.parse(new StringReader(turtle.toString()), RDF.NS.toString());
25 | } catch (Exception e) {
26 | e.printStackTrace();
27 | }
28 | }
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/ValueProcessorIfc.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf;
2 |
3 | import java.util.List;
4 |
5 | import org.apache.poi.ss.usermodel.Cell;
6 | import org.eclipse.rdf4j.model.Model;
7 | import org.eclipse.rdf4j.model.Resource;
8 | import org.eclipse.rdf4j.model.Statement;
9 |
10 | public interface ValueProcessorIfc {
11 |
12 | /**
13 | * Generates one (or more) properties on the given subject from the given value, and insert them in the input model.
14 | * The language is passed as a parameter to be able to overwrite a global language parameter with column-specific language declaration.
15 | *
16 | * @param model
17 | * @param subject
18 | * @param value
19 | * @param language
20 | * @return
21 | */
22 | public List processValue(Model model, Resource subject, String value, Cell cell, String language);
23 |
24 | }
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/Xls2RdfConverterFactory.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import org.eclipse.rdf4j.repository.Repository;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | import fr.sparna.rdf.xls2rdf.postprocess.OWLPostProcessor;
11 | import fr.sparna.rdf.xls2rdf.postprocess.QBPostProcessor;
12 | import fr.sparna.rdf.xls2rdf.postprocess.SkosPostProcessor;
13 | import fr.sparna.rdf.xls2rdf.postprocess.SkosXlPostProcessor;
14 | import fr.sparna.rdf.xls2rdf.reconcile.SparqlReconcileService;
15 | import fr.sparna.rdf.xls2rdf.write.RepositoryModelWriter;
16 |
17 | public class Xls2RdfConverterFactory {
18 |
19 | private Logger log = LoggerFactory.getLogger(this.getClass().getName());
20 |
21 | private boolean applyPostProcessings = true;
22 | private boolean generateXl = false;
23 | private boolean generateXlDefinitions = false;
24 | private boolean noFailOnReconcile = false;
25 | private boolean skipHidden = false;
26 | private final boolean generateBroaderTransitive;
27 | private Repository supportRepository = null;
28 |
29 | public Xls2RdfConverterFactory(
30 | boolean applyPostProcessings,
31 | boolean generateXl,
32 | boolean generateXlDefinitions,
33 | boolean generateBroaderTransitive,
34 | boolean noFailOnReconcile,
35 | boolean skipHidden
36 | ) {
37 | super();
38 | this.applyPostProcessings = applyPostProcessings;
39 | this.generateXl = generateXl;
40 | this.generateXlDefinitions = generateXlDefinitions;
41 | this.generateBroaderTransitive = generateBroaderTransitive;
42 | this.noFailOnReconcile = noFailOnReconcile;
43 | this.skipHidden = skipHidden;
44 | }
45 |
46 | public Xls2RdfConverter newConverter(Repository outputRepository, String lang) {
47 | return this.newConverter(new RepositoryModelWriter(outputRepository), lang);
48 | }
49 |
50 | /**
51 | * @param modelWriter
52 | * @param lang can be null
53 | * @return
54 | */
55 | public Xls2RdfConverter newConverter(ModelWriterIfc modelWriter, String lang) {
56 | Xls2RdfConverter converter = new Xls2RdfConverter(modelWriter, lang);
57 | if(this.applyPostProcessings) {
58 | List postProcessors = new ArrayList<>();
59 | // add QB post processor
60 | postProcessors.add(new QBPostProcessor());
61 | // add OWL post process
62 | postProcessors.add(new OWLPostProcessor());
63 | // add SKOS post processor
64 | postProcessors.add(new SkosPostProcessor(this.generateBroaderTransitive));
65 | // if needed, add SKOS-XL post-processor
66 | if(this.generateXl || this.generateXlDefinitions) {
67 | postProcessors.add(new SkosXlPostProcessor(generateXl, generateXlDefinitions));
68 | }
69 |
70 | converter.setPostProcessors(postProcessors);
71 | }
72 |
73 | if(this.supportRepository != null) {
74 | log.info("Setting a support repository that contains "+this.supportRepository.getConnection().size()+" triples");
75 | converter.setReconcileService(new SparqlReconcileService(this.supportRepository));
76 | }
77 |
78 | converter.setFailIfNoReconcile(!this.noFailOnReconcile);
79 |
80 | converter.setSkipHidden(this.skipHidden);
81 |
82 | return converter;
83 | }
84 |
85 | public boolean isApplyPostProcessings() {
86 | return applyPostProcessings;
87 | }
88 |
89 | public void setApplyPostProcessings(boolean applyPostProcessings) {
90 | this.applyPostProcessings = applyPostProcessings;
91 | }
92 |
93 | public boolean isGenerateXl() {
94 | return generateXl;
95 | }
96 |
97 | public void setGenerateXl(boolean generateXl) {
98 | this.generateXl = generateXl;
99 | }
100 |
101 | public boolean isGenerateXlDefinitions() {
102 | return generateXlDefinitions;
103 | }
104 |
105 | public void setGenerateXlDefinitions(boolean generateXlDefinitions) {
106 | this.generateXlDefinitions = generateXlDefinitions;
107 | }
108 |
109 | public Repository getSupportRepository() {
110 | return supportRepository;
111 | }
112 |
113 | public void setSupportRepository(Repository supportRepository) {
114 | this.supportRepository = supportRepository;
115 | }
116 |
117 | public boolean isNoFailOnReconcile() {
118 | return noFailOnReconcile;
119 | }
120 |
121 | public void setNoFailOnReconcile(boolean noFailOnReconcile) {
122 | this.noFailOnReconcile = noFailOnReconcile;
123 | }
124 |
125 | }
126 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/Xls2RdfException.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf;
2 |
3 | import org.apache.commons.lang3.StringUtils;
4 | import org.slf4j.helpers.MessageFormatter;
5 |
6 | public class Xls2RdfException extends RuntimeException {
7 |
8 | private static final long serialVersionUID = 1L;
9 |
10 | public static void when(boolean test) {
11 | if (test) {
12 | throw new Xls2RdfException("Assertion failed");
13 | }
14 | }
15 |
16 | public static void when(boolean test, String message) {
17 | if (test) {
18 | throw new Xls2RdfException(message);
19 | }
20 | }
21 |
22 | public static void when(boolean test, String message, Object... parameters) {
23 | if (test) {
24 | throw new Xls2RdfException(message, parameters);
25 | }
26 | }
27 |
28 | public static Xls2RdfException rethrow(Throwable exception) {
29 | if (exception instanceof Error) {
30 | throw (Error) exception;
31 | }
32 | if (exception instanceof RuntimeException) {
33 | throw (RuntimeException) exception;
34 | }
35 | throw new Xls2RdfException(exception);
36 | }
37 |
38 | public static T failIfNotInstance(Object object, Class clazz, String message, Object... parameters) {
39 | when(!clazz.isInstance(object), message, parameters);
40 | //noinspection unchecked
41 | return (T) object;
42 | }
43 |
44 | public static T failIfNull(T value, String message, Object... parameters) {
45 | when(null == value, message, parameters);
46 | //noinspection ConstantConditions
47 | return value;
48 | }
49 |
50 | public static T failIfBlank(T value, String message, Object... parameters) {
51 | when(StringUtils.isBlank(value), message, parameters);
52 | //noinspection ConstantConditions
53 | return value;
54 | }
55 |
56 | public Xls2RdfException() {
57 | }
58 |
59 | public Xls2RdfException(String message) {
60 | super(message);
61 | }
62 |
63 | public Xls2RdfException(Throwable cause, String message, Object... parameters) {
64 | super(MessageFormatter.arrayFormat(message, parameters).getMessage(), cause);
65 | }
66 |
67 | public Xls2RdfException(String message, Object... parameters) {
68 | super(MessageFormatter.arrayFormat(message, parameters).getMessage());
69 | }
70 |
71 | public Xls2RdfException(Throwable cause) {
72 | super(cause);
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/Xls2RdfMessageListenerIfc.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf;
2 |
3 | public interface Xls2RdfMessageListenerIfc {
4 |
5 | enum MessageCode {
6 | INVALID_PROPERTY,
7 | WRONG_FORMAT,
8 | UNABLE_TO_RECONCILE_VALUE
9 | }
10 |
11 | public void onMessage(MessageCode code, String cellReference, String message);
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/Xls2RdfPostProcessorIfc.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf;
2 |
3 | import java.util.List;
4 |
5 | import org.eclipse.rdf4j.model.Model;
6 | import org.eclipse.rdf4j.model.Resource;
7 |
8 | public interface Xls2RdfPostProcessorIfc {
9 |
10 | /**
11 | * Post-processes the model converted from a Sheet
12 | *
13 | * @param model full model containing all converted statements
14 | * @param mainResource resource declared in the sheet header
15 | * @param rowResources resources generated from each row (URI in the first column)
16 | * @param columnNames original column headers
17 | */
18 | public void afterSheet(Model model, Resource mainResource, List rowResources, List columnHeaders);
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/listen/ListXls2RdfMessageListener.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.listen;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import fr.sparna.rdf.xls2rdf.Xls2RdfMessageListenerIfc;
7 | import fr.sparna.rdf.xls2rdf.Xls2RdfMessageListenerIfc.MessageCode;
8 |
9 | public class ListXls2RdfMessageListener implements Xls2RdfMessageListenerIfc {
10 |
11 | private List messages = new ArrayList<>();
12 |
13 | @Override
14 | public void onMessage(MessageCode code, String cellReference, String message) {
15 | messages.add(new Message(code, cellReference, message));
16 | }
17 |
18 | public List getMessages() {
19 | return messages;
20 | }
21 |
22 | public class Message {
23 | MessageCode code;
24 | String cellReference;
25 | String message;
26 | public Message(MessageCode code, String cellReference, String message) {
27 | super();
28 | this.code = code;
29 | this.cellReference = cellReference;
30 | this.message = message;
31 | }
32 | public MessageCode getCode() {
33 | return code;
34 | }
35 | public String getCellReference() {
36 | return cellReference;
37 | }
38 | public String getMessage() {
39 | return message;
40 | }
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/listen/LogXls2RdfMessageListener.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.listen;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 |
6 | import fr.sparna.rdf.xls2rdf.Xls2RdfMessageListenerIfc;
7 | import fr.sparna.rdf.xls2rdf.Xls2RdfMessageListenerIfc.MessageCode;
8 |
9 | public class LogXls2RdfMessageListener implements Xls2RdfMessageListenerIfc {
10 |
11 | private Logger log = LoggerFactory.getLogger(this.getClass().getName());
12 |
13 | @Override
14 | public void onMessage(MessageCode code, String cellReference, String message) {
15 | log.info("Cell "+cellReference+" : " +code.name()+" - "+message);
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/postprocess/AsListPostProcessor.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.postprocess;
2 |
3 | import java.util.List;
4 | import java.util.Set;
5 |
6 | import org.eclipse.rdf4j.model.Model;
7 | import org.eclipse.rdf4j.model.Resource;
8 | import org.eclipse.rdf4j.model.Value;
9 | import org.eclipse.rdf4j.model.impl.LinkedHashModel;
10 | import org.eclipse.rdf4j.model.util.RDFCollections;
11 | import org.eclipse.rdf4j.model.util.Values;
12 | import org.slf4j.Logger;
13 | import org.slf4j.LoggerFactory;
14 |
15 | import fr.sparna.rdf.xls2rdf.ColumnHeader;
16 | import fr.sparna.rdf.xls2rdf.Xls2RdfPostProcessorIfc;
17 |
18 | public class AsListPostProcessor implements Xls2RdfPostProcessorIfc {
19 |
20 | private Logger log = LoggerFactory.getLogger(this.getClass().getName());
21 |
22 |
23 | public AsListPostProcessor() {
24 | super();
25 | }
26 |
27 | @Override
28 | public void afterSheet(Model model, Resource mainResource, List rowResources, List columnHeaders) {
29 | log.debug("Postprocessing : "+this.getClass().getSimpleName());
30 |
31 | for (ColumnHeader aHeader : columnHeaders) {
32 | if(aHeader.isAsList()) {
33 | Model toRemove = new LinkedHashModel();
34 | Model toAdd = new LinkedHashModel();
35 | // fetch all subject that have this predicate
36 | Set subjects = model.filter(null, aHeader.getProperty(), null).subjects();
37 | for (Resource aSubject : subjects) {
38 | // gather all the values
39 | Set values = model.filter(aSubject, aHeader.getProperty(), null).objects();
40 | // aggregate in list
41 | Resource listHead = Values.bnode();
42 | RDFCollections.asRDF(values,listHead,toAdd);
43 | // remove all original triples
44 | toRemove.addAll(model.filter(aSubject, aHeader.getProperty(), null));
45 | // add instead triple to the list
46 | toAdd.add(aSubject, aHeader.getProperty(), listHead);
47 | }
48 | // remove everything that needs to be removed
49 | model.removeAll(toRemove);
50 | model.addAll(toAdd);
51 | }
52 | }
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/postprocess/DynamicRdfTypePostProcessor.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.postprocess;
2 |
3 | import java.util.List;
4 | import java.util.function.Predicate;
5 |
6 | import org.eclipse.rdf4j.model.Model;
7 | import org.eclipse.rdf4j.model.Resource;
8 | import org.eclipse.rdf4j.model.vocabulary.RDF;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 |
12 | import fr.sparna.rdf.xls2rdf.ColumnHeader;
13 | import fr.sparna.rdf.xls2rdf.Xls2RdfPostProcessorIfc;
14 |
15 | public class DynamicRdfTypePostProcessor implements Xls2RdfPostProcessorIfc {
16 |
17 | private Logger log = LoggerFactory.getLogger(this.getClass().getName());
18 |
19 | protected Predicate classTest;
20 |
21 | /**
22 | * @param classTest returns true if the provided Resource is a class (e.g. instance of owl:Class or rdfs:Class)
23 | */
24 | public DynamicRdfTypePostProcessor(Predicate classTest) {
25 | super();
26 | this.classTest = classTest;
27 | }
28 |
29 | @Override
30 | public void afterSheet(Model model, Resource mainResource, List rowResources, List columnHeaders) {
31 | log.debug("Postprocessing : "+this.getClass().getSimpleName());
32 | if(this.classTest.test(mainResource)) {
33 | rowResources.stream().forEach(rowResource -> {
34 | if(
35 | model.filter(rowResource, RDF.TYPE, null).isEmpty()
36 | ) {
37 | model.add(rowResource, RDF.TYPE, mainResource);
38 | }
39 | });
40 | }
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/postprocess/OWLPostProcessor.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.postprocess;
2 |
3 | import java.util.List;
4 | import java.util.Set;
5 | import java.util.stream.Collectors;
6 | import java.util.stream.Stream;
7 |
8 | import org.eclipse.rdf4j.model.IRI;
9 | import org.eclipse.rdf4j.model.Model;
10 | import org.eclipse.rdf4j.model.Resource;
11 | import org.eclipse.rdf4j.model.Value;
12 | import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
13 | import org.eclipse.rdf4j.model.util.RDFCollections;
14 | import org.eclipse.rdf4j.model.util.Values;
15 | import org.eclipse.rdf4j.model.vocabulary.OWL;
16 | import org.eclipse.rdf4j.model.vocabulary.RDF;
17 | import org.eclipse.rdf4j.model.vocabulary.RDFS;
18 | import org.slf4j.Logger;
19 | import org.slf4j.LoggerFactory;
20 |
21 | import fr.sparna.rdf.xls2rdf.ColumnHeader;
22 | import fr.sparna.rdf.xls2rdf.Xls2RdfPostProcessorIfc;
23 |
24 | public class OWLPostProcessor implements Xls2RdfPostProcessorIfc {
25 |
26 | private Logger log = LoggerFactory.getLogger(this.getClass().getName());
27 |
28 | public static class XLS2RDF {
29 | public static final String NAMESPACE = "https://xls2rdf.sparna.fr/vocabulary#";
30 |
31 | public static final IRI IS_COVERED_BY = SimpleValueFactory.getInstance().createIRI(NAMESPACE+"isCoveredBy");
32 |
33 | }
34 |
35 | public OWLPostProcessor() {
36 | super();
37 | }
38 |
39 | @Override
40 | public void afterSheet(Model model, Resource mainResource, List rowResources, List columnHeaders) {
41 | log.debug("Postprocessing : "+this.getClass().getSimpleName());
42 |
43 | // if it is said in the graph that the main resource is an owl:Ontology...
44 | if(
45 | model.contains(mainResource, RDF.TYPE, OWL.ONTOLOGY)
46 | ) {
47 | log.debug("Detected a sheet with an owl:Ontology in the header");
48 |
49 |
50 | rowResources.stream().filter(r -> !model.filter(r, XLS2RDF.IS_COVERED_BY, null).isEmpty()).forEach(r -> {
51 | // gather all the is_covered_by values
52 | List isCoveredByValues = model.filter(r, XLS2RDF.IS_COVERED_BY, null).objects().stream()
53 | .filter(v -> (v instanceof IRI))
54 | .map(v -> (IRI)v).collect(Collectors.toList());
55 |
56 | // make an RDF list of this
57 | Resource listHead = Values.bnode();
58 | RDFCollections.asRDF(isCoveredByValues,listHead,model);
59 |
60 | // create union class and add covering axiom
61 | Resource unionClass = Values.bnode();
62 | model.add(unionClass, RDF.TYPE, OWL.CLASS);
63 | model.add(unionClass, OWL.UNIONOF, listHead);
64 | model.add(r, RDFS.SUBCLASSOF, unionClass);
65 |
66 | });
67 |
68 | }
69 | }
70 |
71 | }
72 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/postprocess/QBPostProcessor.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.postprocess;
2 |
3 | import java.util.List;
4 | import java.util.Set;
5 | import java.util.stream.Collectors;
6 | import java.util.stream.Stream;
7 |
8 | import org.eclipse.rdf4j.model.IRI;
9 | import org.eclipse.rdf4j.model.Model;
10 | import org.eclipse.rdf4j.model.Resource;
11 | import org.eclipse.rdf4j.model.Value;
12 | import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
13 | import org.eclipse.rdf4j.model.vocabulary.RDF;
14 | import org.slf4j.Logger;
15 | import org.slf4j.LoggerFactory;
16 |
17 | import fr.sparna.rdf.xls2rdf.ColumnHeader;
18 | import fr.sparna.rdf.xls2rdf.Xls2RdfPostProcessorIfc;
19 |
20 | public class QBPostProcessor implements Xls2RdfPostProcessorIfc {
21 |
22 | public static class QB {
23 | public static final String QB = "http://purl.org/linked-data/cube#";
24 |
25 | public static final IRI DATASET_CLASS = SimpleValueFactory.getInstance().createIRI(QB+"DataSet");
26 |
27 | public static final IRI OBSERVATION = SimpleValueFactory.getInstance().createIRI(QB+"Observation");
28 |
29 | public static final IRI COMPONENT_SPECIFICATION = SimpleValueFactory.getInstance().createIRI(QB+"ComponentSpecification");
30 |
31 | public static final IRI DATA_STRUCTURE_DEFINITION = SimpleValueFactory.getInstance().createIRI(QB+"DataStructureDefinition");
32 |
33 | public static final IRI DATASET_PROPERTY = SimpleValueFactory.getInstance().createIRI(QB+"dataSet");
34 |
35 | public static final IRI STRUCTURE = SimpleValueFactory.getInstance().createIRI(QB+"structure");
36 |
37 | public static final IRI DIMENSION = SimpleValueFactory.getInstance().createIRI(QB+"dimension");
38 |
39 | public static final IRI MEASURE = SimpleValueFactory.getInstance().createIRI(QB+"measure");
40 |
41 | public static final IRI COMPONENT = SimpleValueFactory.getInstance().createIRI(QB+"component");
42 | }
43 |
44 |
45 | private Logger log = LoggerFactory.getLogger(this.getClass().getName());
46 |
47 | public QBPostProcessor() {
48 | super();
49 | }
50 |
51 | @Override
52 | public void afterSheet(Model model, Resource mainResource, List rowResources, List columnHeaders) {
53 | log.debug("Postprocessing : "+this.getClass().getSimpleName());
54 |
55 | // if it is said in the graph that the main resource is a qb:DataSet...
56 | if(
57 | model.contains(mainResource, RDF.TYPE, QB.DATASET_CLASS)
58 | ) {
59 | log.debug("Detected a sheet with a qb:DataSet in the header");
60 |
61 | // if the dataset has a qb:structure
62 | // then 1/ everything with either a qb:dimension or qb:measure is considered a qb:ComponentSpecification and
63 | // and 2/ they are linked with the structure
64 | Set structures = model.filter(mainResource, QB.STRUCTURE, null).objects();
65 |
66 | if(structures.size() > 0) {
67 | if(structures.size() > 1) {
68 | log.error("Found multiple structure on Dataset "+mainResource+" : "+structures+", can't attach components");
69 | } else {
70 | Value structureValue = structures.iterator().next();
71 |
72 | if(structureValue instanceof Resource) {
73 | Resource structure = (Resource)structureValue;
74 |
75 | Stream.concat(
76 | model.filter(null, QB.DIMENSION, null).subjects().stream(),
77 | model.filter(null, QB.MEASURE, null).subjects().stream()
78 | ).forEach(c -> {
79 | model.add(c, RDF.TYPE, QB.COMPONENT_SPECIFICATION);
80 | model.add(structure, QB.COMPONENT, c);
81 | });
82 |
83 | // also type the structure
84 | model.add(structure, RDF.TYPE, QB.DATA_STRUCTURE_DEFINITION);
85 | } else {
86 | log.error("Found structure not a Resource :"+structureValue+", can't attach components");
87 | }
88 | }
89 | }
90 |
91 | // then every resource in the sheet without a type will be considered an Observation, linked to this Dataset
92 | rowResources.stream().filter(r -> model.filter(r, RDF.TYPE, null).isEmpty()).forEach(r -> {
93 | model.add(r, RDF.TYPE, QB.OBSERVATION);
94 | model.add(r, QB.DATASET_PROPERTY, mainResource);
95 | });
96 |
97 | }
98 |
99 |
100 | }
101 |
102 | }
103 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/postprocess/RdfTypePostProcessor.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.postprocess;
2 |
3 | import org.eclipse.rdf4j.model.IRI;
4 | import org.eclipse.rdf4j.model.vocabulary.RDF;
5 |
6 | public class RdfTypePostProcessor extends RowHeaderLinkPostProcessor {
7 |
8 | public RdfTypePostProcessor(IRI property, boolean addOnlyIfNotPresent) {
9 | super(RDF.TYPE, true);
10 | }
11 |
12 | }
13 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/postprocess/RowHeaderLinkPostProcessor.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.postprocess;
2 |
3 | import java.util.List;
4 |
5 | import org.eclipse.rdf4j.model.IRI;
6 | import org.eclipse.rdf4j.model.Model;
7 | import org.eclipse.rdf4j.model.Resource;
8 |
9 | import fr.sparna.rdf.xls2rdf.ColumnHeader;
10 | import fr.sparna.rdf.xls2rdf.Xls2RdfPostProcessorIfc;
11 |
12 | public class RowHeaderLinkPostProcessor implements Xls2RdfPostProcessorIfc {
13 |
14 | protected IRI property;
15 | protected boolean addOnlyIfNotPresent = true;
16 |
17 | public RowHeaderLinkPostProcessor(IRI property, boolean addOnlyIfNotPresent) {
18 | super();
19 | this.property = property;
20 | this.addOnlyIfNotPresent = addOnlyIfNotPresent;
21 | }
22 |
23 | @Override
24 | public void afterSheet(Model model, Resource mainResource, List rowResources, List columnHeaders) {
25 | rowResources.stream().forEach(rowResource -> {
26 | if(
27 | !this.addOnlyIfNotPresent
28 | ||
29 | !model.contains(rowResource, this.property, null)
30 | ) {
31 | model.add(rowResource, this.property, mainResource);
32 | }
33 | });
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/postprocess/SkosXlPostProcessor.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.postprocess;
2 |
3 | import java.io.InputStream;
4 | import java.util.Arrays;
5 | import java.util.List;
6 |
7 | import org.apache.commons.io.IOUtils;
8 | import org.eclipse.rdf4j.model.Model;
9 | import org.eclipse.rdf4j.model.Resource;
10 | import org.eclipse.rdf4j.model.Statement;
11 | import org.eclipse.rdf4j.query.Update;
12 | import org.eclipse.rdf4j.repository.Repository;
13 | import org.eclipse.rdf4j.repository.RepositoryConnection;
14 | import org.eclipse.rdf4j.repository.sail.SailRepository;
15 | import org.eclipse.rdf4j.rio.RDFHandlerException;
16 | import org.eclipse.rdf4j.rio.helpers.AbstractRDFHandler;
17 | import org.eclipse.rdf4j.sail.memory.MemoryStore;
18 | import org.slf4j.Logger;
19 | import org.slf4j.LoggerFactory;
20 |
21 | import fr.sparna.rdf.xls2rdf.ColumnHeader;
22 | import fr.sparna.rdf.xls2rdf.Xls2RdfException;
23 | import fr.sparna.rdf.xls2rdf.Xls2RdfPostProcessorIfc;
24 |
25 | public class SkosXlPostProcessor implements Xls2RdfPostProcessorIfc {
26 |
27 | private Logger log = LoggerFactory.getLogger(this.getClass().getName());
28 |
29 | /**
30 | * Whether to automatically generates SKOS-XL labels
31 | */
32 | protected boolean generateXl = true;
33 |
34 | /**
35 | * Whether to automatically reify definitions (for Vocbench)
36 | */
37 | private boolean generateXlDefinitions = false;
38 |
39 | public SkosXlPostProcessor(boolean generateXl, boolean generateXlDefinitions) {
40 | super();
41 | this.generateXl = generateXl;
42 | this.generateXlDefinitions = generateXlDefinitions;
43 | }
44 |
45 | @Override
46 | public void afterSheet(Model model, Resource mainResource, List rowResources, List columnHeaders) {
47 | log.debug("Postprocessing : "+this.getClass().getSimpleName());
48 |
49 | Repository r = new SailRepository(new MemoryStore());
50 | r.init();
51 |
52 | try(RepositoryConnection c = r.getConnection()) {
53 | c.add(model);
54 |
55 | if(this.generateXl) {
56 | final List SKOS2SKOSXL_URI_RULESET = Arrays.asList(new String[] {
57 | "skos2skosxl/S55-S56-S57-URIs.ru"
58 | });
59 |
60 | for (String aString : SKOS2SKOSXL_URI_RULESET) {
61 | // Load SPARQL query definition
62 | InputStream src = this.getClass().getResourceAsStream(aString);
63 | String sparql = IOUtils.toString(src);
64 | Update u = c.prepareUpdate(sparql);
65 | u.execute();
66 | }
67 | }
68 |
69 | if(this.generateXlDefinitions) {
70 | final List SKOS2SKOSXL_NOTES_URI_RULESET = Arrays.asList(new String[] {
71 | "skos2skosxl/S16-URIs.ru"
72 | });
73 |
74 | for (String aString : SKOS2SKOSXL_NOTES_URI_RULESET) {
75 | // Load SPARQL query definition
76 | InputStream src = this.getClass().getResourceAsStream(aString);
77 | String sparql = IOUtils.toString(src);
78 | Update u = c.prepareUpdate(sparql);
79 | u.execute();
80 | }
81 | }
82 |
83 | // re-export to a new Model
84 | model.clear();
85 | c.export(new AbstractRDFHandler() {
86 | public void handleStatement(Statement st) throws RDFHandlerException {
87 | model.add(st);
88 | }
89 | });
90 | } catch (Exception e) {
91 | throw Xls2RdfException.rethrow(e);
92 | }
93 |
94 | }
95 |
96 | }
97 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/reconcile/DummyReconcileService.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.reconcile;
2 |
3 | import java.io.UnsupportedEncodingException;
4 | import java.net.URLEncoder;
5 | import java.util.HashMap;
6 | import java.util.Map;
7 |
8 | import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
9 |
10 | public class DummyReconcileService implements ReconcileServiceIfc {
11 |
12 | private final String rootUri;
13 |
14 | public DummyReconcileService(String rootUri) {
15 | super();
16 | this.rootUri = rootUri;
17 | }
18 |
19 | @Override
20 | public Map reconcile(Map queries) {
21 |
22 | Map result = new HashMap();
23 |
24 | for (Map.Entry anEntry : queries.entrySet()) {
25 | try {
26 | result.put(
27 | anEntry.getKey(),
28 | new SimpleReconcileResult(
29 | SimpleValueFactory.getInstance().createIRI(this.rootUri+"/"+URLEncoder.encode(anEntry.getValue().getQuery(), "UTF-8")).toString(),
30 | anEntry.getValue().getQuery(),
31 | (anEntry.getValue().getTypes() != null && anEntry.getValue().getTypes().size() > 0)?anEntry.getValue().getTypes().get(0):null
32 | )
33 | );
34 | } catch (UnsupportedEncodingException e) {
35 | e.printStackTrace();
36 | }
37 | }
38 |
39 | return result;
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/reconcile/DynamicReconciliableValueSet.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.reconcile;
2 |
3 | import java.util.Collections;
4 | import java.util.HashMap;
5 | import java.util.Map;
6 |
7 | import org.eclipse.rdf4j.model.IRI;
8 | import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
9 | import org.slf4j.Logger;
10 | import org.slf4j.LoggerFactory;
11 |
12 | import fr.sparna.rdf.xls2rdf.Xls2RdfException;
13 | import fr.sparna.rdf.xls2rdf.Xls2RdfMessageListenerIfc;
14 | import fr.sparna.rdf.xls2rdf.Xls2RdfMessageListenerIfc.MessageCode;
15 |
16 | public class DynamicReconciliableValueSet implements ReconciliableValueSetIfc {
17 |
18 | private static Logger log = LoggerFactory.getLogger(DynamicReconciliableValueSet.class.getName());
19 |
20 | private transient ReconcileServiceIfc reconcileService;
21 | private IRI reconcileType;
22 | private boolean failOnNoMatch = true;
23 | private Xls2RdfMessageListenerIfc messageListener;
24 |
25 | private Map reconciledValues;
26 |
27 |
28 | public DynamicReconciliableValueSet(
29 | ReconcileServiceIfc reconcileService,
30 | IRI reconcileType,
31 | boolean failOnNoMatch,
32 | Xls2RdfMessageListenerIfc messageListener
33 | ) {
34 | this.reconcileService = reconcileService;
35 | this.failOnNoMatch = failOnNoMatch;
36 | this.reconcileType = reconcileType;
37 | this.messageListener = messageListener;
38 | this.reconciledValues = new HashMap();
39 | }
40 |
41 | /* (non-Javadoc)
42 | * @see fr.sparna.rdf.skos.xls2skos.reconcile.ReconciliableValueSetIfc#getReconciledValue(java.lang.String)
43 | */
44 | @Override
45 | public IRI getReconciledValue(String value) {
46 | if(!reconciledValues.containsKey(value)) {
47 | Map result = reconcileSingleValue(value, this.reconcileType);
48 | this.reconciledValues.putAll(result);
49 | }
50 |
51 | return this.reconciledValues.get(value);
52 | }
53 |
54 | private Map reconcileSingleValue(String value, IRI reconcileType) {
55 |
56 | // build the queries Map
57 | Map queries = new HashMap();
58 | queries.put("q0", new SimpleReconcileQuery(
59 | value,
60 | (reconcileType != null)?Collections.singletonList(reconcileType.toString()):null
61 | ));
62 |
63 | // call ReconcileService
64 | Map reconcileResults = this.reconcileService.reconcile(queries);
65 |
66 | // parse results
67 | Map result = new HashMap();
68 | for (Map.Entry anEntry : reconcileResults.entrySet()) {
69 |
70 | String initialValue = queries.get(anEntry.getKey()).getQuery();
71 |
72 | if(anEntry.getValue().getMatches() == null || anEntry.getValue().getMatches().size() == 0) {
73 | // no reconciliation result for this value
74 | String message = "Unable to reconcile value '"+ initialValue +"' on type/scheme <"+ reconcileType +">";
75 | if(this.failOnNoMatch) {
76 | throw new Xls2RdfException(message);
77 | } else {
78 | this.messageListener.onMessage(MessageCode.UNABLE_TO_RECONCILE_VALUE, "??", message);
79 | log.error(message);
80 | }
81 | } else {
82 | // pick the first one, assuming only one result for now
83 | String matchResult = anEntry.getValue().getMatches().get(0).getId();
84 | log.debug("Value '"+initialValue+"' reconciled to <"+matchResult+">");
85 | result.put(initialValue, SimpleValueFactory.getInstance().createIRI(anEntry.getValue().getMatches().get(0).getId()));
86 | }
87 | }
88 |
89 | return result;
90 | }
91 |
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/reconcile/ReconcileMatchIfc.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.reconcile;
2 |
3 | import java.util.List;
4 |
5 | public interface ReconcileMatchIfc {
6 |
7 | public String getId();
8 |
9 | public String getName();
10 |
11 | public List getTypes();
12 |
13 | public double getScore();
14 |
15 | public boolean isMatch();
16 |
17 | }
18 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/reconcile/ReconcileQueryIfc.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.reconcile;
2 |
3 | import java.util.List;
4 |
5 | public interface ReconcileQueryIfc {
6 |
7 | /**
8 | * String to search for
9 | * @return
10 | */
11 | public String getQuery();
12 |
13 | /**
14 | * Optional types of the expected result
15 | * @return
16 | */
17 | public List getTypes();
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/reconcile/ReconcileResultIfc.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.reconcile;
2 |
3 | import java.util.List;
4 |
5 | public interface ReconcileResultIfc {
6 |
7 | public List getMatches();
8 |
9 | }
10 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/reconcile/ReconcileServiceIfc.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.reconcile;
2 |
3 | import java.util.Map;
4 |
5 | public interface ReconcileServiceIfc {
6 |
7 |
8 | public Map reconcile(Map queries);
9 |
10 | }
11 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/reconcile/ReconciliableValueSetIfc.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.reconcile;
2 |
3 | import org.eclipse.rdf4j.model.IRI;
4 |
5 | public interface ReconciliableValueSetIfc {
6 |
7 | IRI getReconciledValue(String value);
8 |
9 | }
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/reconcile/SimpleReconcileMatch.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.reconcile;
2 |
3 | import java.util.Collections;
4 | import java.util.List;
5 |
6 | public class SimpleReconcileMatch implements ReconcileMatchIfc {
7 |
8 | private String id;
9 | private String name;
10 | private List types;
11 | private double score;
12 | private boolean match;
13 |
14 | public SimpleReconcileMatch(String id, String name, String type) {
15 | this(id, name, Collections.singletonList(type), 1.0d, true);
16 | }
17 |
18 | public SimpleReconcileMatch(String id, String name, List types, double score, boolean match) {
19 | super();
20 | this.id = id;
21 | this.name = name;
22 | this.types = types;
23 | this.score = score;
24 | this.match = match;
25 | }
26 |
27 | public void setId(String id) {
28 | this.id = id;
29 | }
30 |
31 | public void setName(String name) {
32 | this.name = name;
33 | }
34 |
35 | public void setTypes(List types) {
36 | this.types = types;
37 | }
38 |
39 | public void setScore(double score) {
40 | this.score = score;
41 | }
42 |
43 | public void setMatch(boolean match) {
44 | this.match = match;
45 | }
46 |
47 | @Override
48 | public String getId() {
49 | return id;
50 | }
51 |
52 | @Override
53 | public String getName() {
54 | return name;
55 | }
56 |
57 | @Override
58 | public List getTypes() {
59 | return types;
60 | }
61 |
62 | @Override
63 | public double getScore() {
64 | return score;
65 | }
66 |
67 | @Override
68 | public boolean isMatch() {
69 | return match;
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/reconcile/SimpleReconcileQuery.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.reconcile;
2 |
3 | import java.util.List;
4 |
5 | public class SimpleReconcileQuery implements ReconcileQueryIfc {
6 |
7 | private String query;
8 | private List types;
9 |
10 | public SimpleReconcileQuery(String query) {
11 | super();
12 | this.query = query;
13 | }
14 |
15 | public SimpleReconcileQuery(String query, List types) {
16 | super();
17 | this.query = query;
18 | this.types = types;
19 | }
20 |
21 | public void setQuery(String query) {
22 | this.query = query;
23 | }
24 |
25 | public void setTypes(List types) {
26 | this.types = types;
27 | }
28 |
29 | @Override
30 | public String getQuery() {
31 | return query;
32 | }
33 |
34 | @Override
35 | public List getTypes() {
36 | return types;
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/reconcile/SimpleReconcileResult.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.reconcile;
2 |
3 | import java.util.Collections;
4 | import java.util.List;
5 |
6 | public class SimpleReconcileResult implements ReconcileResultIfc {
7 |
8 | private List matches;
9 |
10 | public SimpleReconcileResult() {
11 | super();
12 | }
13 |
14 | public SimpleReconcileResult(String id, String name, String type) {
15 | this(Collections.singletonList(new SimpleReconcileMatch(id, name, type)));
16 | }
17 |
18 | public SimpleReconcileResult(List matches) {
19 | super();
20 | this.matches = matches;
21 | }
22 |
23 | public void setMatches(List matches) {
24 | this.matches = matches;
25 | }
26 |
27 | @Override
28 | public List getMatches() {
29 | return matches;
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/reconcile/SparqlReconcileService.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.reconcile;
2 |
3 | import java.util.HashMap;
4 | import java.util.List;
5 | import java.util.Map;
6 |
7 | import org.eclipse.rdf4j.query.AbstractTupleQueryResultHandler;
8 | import org.eclipse.rdf4j.query.BindingSet;
9 | import org.eclipse.rdf4j.query.TupleQuery;
10 | import org.eclipse.rdf4j.query.TupleQueryResultHandlerException;
11 | import org.eclipse.rdf4j.repository.Repository;
12 | import org.eclipse.rdf4j.repository.RepositoryConnection;
13 | import org.slf4j.Logger;
14 | import org.slf4j.LoggerFactory;
15 |
16 | public class SparqlReconcileService implements ReconcileServiceIfc {
17 |
18 | private Logger log = LoggerFactory.getLogger(this.getClass().getName());
19 |
20 | private Repository repository;
21 |
22 | public SparqlReconcileService(Repository repository) {
23 | super();
24 | this.repository = repository;
25 | }
26 |
27 | @Override
28 | public Map reconcile(Map queries) {
29 | Map result = new HashMap();
30 |
31 | try(RepositoryConnection c = this.repository.getConnection()) {
32 | for (Map.Entry anEntry : queries.entrySet()) {
33 | ReconcileQueryIfc aQuery = anEntry.getValue();
34 |
35 | String sparql = ""
36 | + "PREFIX rdfs: "+"\n"
37 | + "PREFIX skos: "+"\n"
38 | + "PREFIX foaf: "+"\n"
39 | + "PREFIX dct: "+"\n"
40 | + "PREFIX dc: "+"\n"
41 | + "PREFIX schema: "+"\n"
42 | + "SELECT ?x WHERE { "+"\n"
43 | + " ?x rdfs:label|skos:prefLabel|skos:altLabel|skos:notation|foaf:name|dct:title|dc:title|dct:identifier|dc:identifier|schema:name ?literal ."+"\n"
44 | + " FILTER(LCASE(STR(?literal)) = LCASE(\"%s\") )"+"\n"
45 | + " %s "+"\n"
46 | + "}"
47 | ;
48 |
49 | String finalSparql = String.format(
50 | sparql,
51 | aQuery.getQuery(),
52 | ((aQuery.getTypes() != null && aQuery.getTypes().size() > 0)?" ?x rdf:type|skos:inScheme <"+aQuery.getTypes().get(0)+"> .":"")
53 | );
54 |
55 | log.trace("Executing reconcile SPARQL : "+finalSparql);
56 | // System.out.println("Executing reconcile SPARQL : "+finalSparql);
57 | TupleQuery query = c.prepareTupleQuery(finalSparql);
58 | query.evaluate(new AbstractTupleQueryResultHandler() {
59 |
60 | @Override
61 | public void startQueryResult(List bindingNames) throws TupleQueryResultHandlerException {
62 | // always put an empty result for every query
63 | // that can be overwritten if there is a match
64 | // there must be one result in the output for every sent query
65 | result.put(
66 | anEntry.getKey(),
67 | new SimpleReconcileResult()
68 | );
69 | }
70 |
71 | @Override
72 | public void handleSolution(BindingSet bindingSet) throws TupleQueryResultHandlerException {
73 | result.put(
74 | anEntry.getKey(),
75 | new SimpleReconcileResult(
76 | bindingSet.getBinding("x").getValue().toString(),
77 | null,
78 | null
79 | )
80 | );
81 | }
82 |
83 | });
84 |
85 |
86 | }
87 | }
88 |
89 |
90 | return result;
91 | }
92 |
93 |
94 |
95 | }
96 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/write/DirectoryModelWriter.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.write;
2 |
3 |
4 | import java.io.File;
5 | import java.io.FileOutputStream;
6 | import java.net.URLEncoder;
7 | import java.util.HashMap;
8 | import java.util.Map;
9 |
10 | import org.apache.commons.io.IOUtils;
11 | import org.eclipse.rdf4j.model.Model;
12 | import org.eclipse.rdf4j.model.vocabulary.DCTERMS;
13 | import org.eclipse.rdf4j.model.vocabulary.SKOS;
14 | import org.eclipse.rdf4j.repository.Repository;
15 | import org.eclipse.rdf4j.repository.RepositoryConnection;
16 | import org.eclipse.rdf4j.repository.sail.SailRepository;
17 | import org.eclipse.rdf4j.rio.RDFFormat;
18 | import org.eclipse.rdf4j.rio.RDFHandler;
19 | import org.eclipse.rdf4j.rio.RDFWriter;
20 | import org.eclipse.rdf4j.rio.RDFWriterRegistry;
21 | import org.eclipse.rdf4j.rio.helpers.BufferedGroupingRDFHandler;
22 | import org.eclipse.rdf4j.sail.memory.MemoryStore;
23 |
24 | import fr.sparna.rdf.xls2rdf.ModelWriterIfc;
25 | import fr.sparna.rdf.xls2rdf.Xls2RdfException;
26 |
27 | /**
28 | * Saves each Model in a separate file in the given directory, and optionnaly generates a graph file for easy loading into Virtuoso.
29 | *
30 | * @author thomas
31 | *
32 | */
33 | public class DirectoryModelWriter implements ModelWriterIfc {
34 |
35 | private File outputFolder;
36 | private boolean saveGraphFile = true;
37 | private RDFFormat format = RDFFormat.RDFXML;
38 | private String graphSuffix = null;
39 |
40 | private Map modelsByGraph = new HashMap<>();
41 | private Map> prefixesByGraph = new HashMap<>();
42 |
43 | private Map baseIriByGraph = new HashMap<>();
44 |
45 | private boolean grouping = true;
46 |
47 | public DirectoryModelWriter(File outputFolder) {
48 | super();
49 | this.outputFolder = outputFolder;
50 | }
51 |
52 | /* (non-Javadoc)
53 | * @see fr.sparna.rdf.skos.xls2skos.ModelSaverIfc#saveGraphModel(java.lang.String, org.eclipse.rdf4j.model.Model)
54 | */
55 | @Override
56 | public void saveGraphModel(String graph, Model model, Map prefixes, String baseIri) {
57 | graph = graph + ((this.graphSuffix != null)?graphSuffix:"");
58 |
59 | if(modelsByGraph.containsKey(graph)) {
60 | modelsByGraph.get(graph).addAll(model);
61 | } else {
62 | modelsByGraph.put(graph, model);
63 | }
64 |
65 | prefixesByGraph.put(graph, prefixes);
66 | baseIriByGraph.put(graph, baseIri);
67 | }
68 |
69 | public void exportModel(Model model, RDFHandler handler, Map prefixes) {
70 | Repository r = new SailRepository(new MemoryStore());
71 | r.init();
72 | try(RepositoryConnection c = r.getConnection()) {
73 | // register the prefixes
74 | prefixes.entrySet().forEach(e -> c.setNamespace(e.getKey(), e.getValue()));
75 | c.add(model);
76 | c.export(handler);
77 | }
78 | }
79 |
80 | public String getGraphSuffix() {
81 | return graphSuffix;
82 | }
83 |
84 | public void setGraphSuffix(String graphSuffix) {
85 | this.graphSuffix = graphSuffix;
86 | }
87 |
88 | @Override
89 | public void beginWorkbook() {
90 |
91 | }
92 |
93 | @Override
94 | public void endWorkbook() {
95 |
96 | for (Map.Entry anEntry : this.modelsByGraph.entrySet()) {
97 | String graph = anEntry.getKey();
98 | Model model = anEntry.getValue();
99 |
100 | try {
101 | String filename = URLEncoder.encode(graph, "UTF-8");
102 | File file = new File(outputFolder, filename + "." + format.getDefaultFileExtension());
103 | try (FileOutputStream fos = new FileOutputStream(file)) {
104 |
105 | RDFHandler handler = RDFHandlerFactory.buildHandler(grouping, filename, format, fos);
106 | exportModel(model, handler, prefixesByGraph.get(graph));
107 | fos.flush();
108 | } catch (Exception e) {
109 | throw new RuntimeException("Failed to save model", e);
110 | }
111 |
112 | if(saveGraphFile) {
113 | File graphFile = new File(outputFolder, file.getName() + ".graph");
114 | IOUtils.write(graph, new FileOutputStream(graphFile));
115 | }
116 | } catch(Exception e) {
117 | throw Xls2RdfException.rethrow(e);
118 | }
119 | }
120 |
121 | // reset accumulated data so that the same writer does not accumulate data between every files
122 | this.modelsByGraph = new HashMap<>();
123 | this.prefixesByGraph = new HashMap<>();
124 | }
125 |
126 | public boolean isSaveGraphFile() {
127 | return saveGraphFile;
128 | }
129 |
130 | public void setSaveGraphFile(boolean saveGraphFile) {
131 | this.saveGraphFile = saveGraphFile;
132 | }
133 |
134 | public RDFFormat getFormat() {
135 | return format;
136 | }
137 |
138 | public void setFormat(RDFFormat format) {
139 | this.format = format;
140 | }
141 |
142 | public boolean isGrouping() {
143 | return grouping;
144 | }
145 |
146 | public void setGrouping(boolean grouping) {
147 | this.grouping = grouping;
148 | }
149 |
150 | }
151 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/write/ModelWriterFactory.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.write;
2 |
3 | import java.io.File;
4 | import java.io.OutputStream;
5 |
6 | import org.eclipse.rdf4j.rio.RDFFormat;
7 |
8 | import fr.sparna.rdf.xls2rdf.ModelWriterIfc;
9 |
10 | public class ModelWriterFactory {
11 |
12 | protected boolean useZip = false;
13 | protected boolean useGraph = false;
14 | protected RDFFormat format;
15 | protected boolean grouping = true;
16 |
17 | public ModelWriterFactory(boolean useZip, RDFFormat format) {
18 | super();
19 | this.useZip = useZip;
20 | this.format = format;
21 | }
22 |
23 | public ModelWriterFactory(boolean useZip, RDFFormat format, boolean useGraph) {
24 | super();
25 | this.useZip = useZip;
26 | this.format = format;
27 | this.useGraph = useGraph;
28 | }
29 |
30 | public ModelWriterIfc buildNewModelWriter(OutputStream out) {
31 | // if useGraph, force a ZIP output
32 | if(useGraph || useZip) {
33 | ZipOutputStreamModelWriter modelWriter = new ZipOutputStreamModelWriter(out);
34 | modelWriter.setFormat(format);
35 | modelWriter.setSaveGraphFile(useGraph);
36 | modelWriter.setGrouping(this.grouping);
37 | return modelWriter;
38 | } else {
39 | OutputStreamModelWriter modelWriter = new OutputStreamModelWriter(out);
40 | modelWriter.setFormat(format);
41 | modelWriter.setGrouping(this.grouping);
42 | return modelWriter;
43 | }
44 | }
45 |
46 | public ModelWriterIfc buildNewModelWriter(File directory) {
47 | if(!directory.exists()) {
48 | directory.mkdirs();
49 | }
50 | DirectoryModelWriter modelWriter = new DirectoryModelWriter(directory);
51 | modelWriter.setFormat(format);
52 | modelWriter.setSaveGraphFile(this.useGraph);
53 | modelWriter.setGrouping(this.grouping);
54 | return modelWriter;
55 | }
56 |
57 | public boolean isUseZip() {
58 | return useZip;
59 | }
60 |
61 | public void setUseZip(boolean useZip) {
62 | this.useZip = useZip;
63 | }
64 |
65 | public RDFFormat getFormat() {
66 | return format;
67 | }
68 |
69 | public void setFormat(RDFFormat format) {
70 | this.format = format;
71 | }
72 |
73 | public boolean isUseGraph() {
74 | return useGraph;
75 | }
76 |
77 | public void setUseGraph(boolean useGraph) {
78 | this.useGraph = useGraph;
79 | }
80 |
81 | public boolean isGrouping() {
82 | return grouping;
83 | }
84 |
85 | public void setGrouping(boolean grouping) {
86 | this.grouping = grouping;
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/write/OutputStreamModelWriter.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.write;
2 |
3 | import java.io.File;
4 | import java.io.FileOutputStream;
5 | import java.io.OutputStream;
6 | import java.net.URISyntaxException;
7 | import java.util.Map;
8 |
9 | import org.eclipse.rdf4j.model.Model;
10 | import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
11 | import org.eclipse.rdf4j.model.vocabulary.SKOS;
12 | import org.eclipse.rdf4j.repository.Repository;
13 | import org.eclipse.rdf4j.repository.RepositoryConnection;
14 | import org.eclipse.rdf4j.repository.sail.SailRepository;
15 | import org.eclipse.rdf4j.rio.RDFFormat;
16 | import org.eclipse.rdf4j.rio.RDFHandler;
17 | import org.eclipse.rdf4j.rio.RDFWriterRegistry;
18 | import org.eclipse.rdf4j.rio.helpers.BufferedGroupingRDFHandler;
19 | import org.eclipse.rdf4j.sail.memory.MemoryStore;
20 |
21 | import fr.sparna.rdf.xls2rdf.ModelWriterIfc;
22 | import fr.sparna.rdf.xls2rdf.SKOSXL;
23 | import fr.sparna.rdf.xls2rdf.Xls2RdfException;
24 |
25 | /**
26 | * @author thomas
27 | *
28 | */
29 | public class OutputStreamModelWriter implements ModelWriterIfc {
30 |
31 | private OutputStream out;
32 | private RDFFormat format = RDFFormat.RDFXML;
33 | private Repository outputRepository;
34 |
35 | private boolean grouping = true;
36 |
37 | private String baseIri;
38 |
39 | public OutputStreamModelWriter(OutputStream out) {
40 | super();
41 | this.out = out;
42 | }
43 |
44 | public OutputStreamModelWriter(File f) {
45 | super();
46 | try {
47 | if(!f.exists()) {
48 | f.createNewFile();
49 | }
50 | this.out = new FileOutputStream(f);
51 | // determine format automatically based on file extension
52 | this.format = RDFWriterRegistry.getInstance().getFileFormatForFileName(f.getName()).get();
53 | } catch (Exception e) {
54 | throw new RuntimeException(e);
55 | }
56 | }
57 |
58 | /* (non-Javadoc)
59 | * @see fr.sparna.rdf.skos.xls2skos.ModelSaverIfc#saveGraphModel(java.lang.String, org.eclipse.rdf4j.model.Model)
60 | */
61 | @Override
62 | public void saveGraphModel(String graph, Model model, Map prefixes, String baseIri) {
63 | try {
64 | try(RepositoryConnection c = this.outputRepository.getConnection()) {
65 | // register the prefixes
66 | prefixes.entrySet().forEach(e -> c.setNamespace(e.getKey(), e.getValue()));
67 | c.add(model, SimpleValueFactory.getInstance().createIRI(graph));
68 | }
69 |
70 | // keep track of baseIri
71 | this.baseIri = baseIri;
72 | } catch(Exception e) {
73 | throw Xls2RdfException.rethrow(e);
74 | }
75 | }
76 |
77 | @Override
78 | public void beginWorkbook() {
79 | this.outputRepository = new SailRepository(new MemoryStore());
80 | this.outputRepository.init();
81 |
82 | }
83 |
84 | @Override
85 | public void endWorkbook() {
86 | try {
87 | RDFHandler handler = RDFHandlerFactory.buildHandler(grouping, baseIri, format, out);
88 |
89 | try(RepositoryConnection c = this.outputRepository.getConnection()) {
90 | c.setNamespace("skos", SKOS.NAMESPACE);
91 | c.setNamespace("skosxl", SKOSXL.NAMESPACE);
92 | c.export(handler);
93 | }
94 |
95 | out.flush();
96 | } catch (Exception e) {
97 | throw new RuntimeException(e);
98 | }
99 | }
100 |
101 | public RDFFormat getFormat() {
102 | return format;
103 | }
104 |
105 | public void setFormat(RDFFormat format) {
106 | this.format = format;
107 | }
108 |
109 | public boolean isGrouping() {
110 | return grouping;
111 | }
112 |
113 | public void setGrouping(boolean grouping) {
114 | this.grouping = grouping;
115 | }
116 |
117 |
118 | }
119 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/write/RDFHandlerFactory.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.write;
2 |
3 | import java.io.OutputStream;
4 | import java.net.URISyntaxException;
5 |
6 | import org.eclipse.rdf4j.rio.RDFFormat;
7 | import org.eclipse.rdf4j.rio.RDFHandler;
8 | import org.eclipse.rdf4j.rio.RDFWriterRegistry;
9 | import org.eclipse.rdf4j.rio.helpers.BufferedGroupingRDFHandler;
10 |
11 | public class RDFHandlerFactory {
12 |
13 | public static RDFHandler buildHandler(boolean grouping, String baseIri, RDFFormat format, OutputStream out)
14 | throws URISyntaxException {
15 | RDFHandler handler;
16 | if(baseIri != null) {
17 | if(grouping) {
18 | handler = new BufferedGroupingRDFHandler(100000, RDFWriterRegistry.getInstance().get(format).get().getWriter(out, baseIri));
19 | } else {
20 | handler = RDFWriterRegistry.getInstance().get(format).get().getWriter(out, baseIri);
21 | }
22 | } else {
23 | if(grouping) {
24 | handler = new BufferedGroupingRDFHandler(100000, RDFWriterRegistry.getInstance().get(format).get().getWriter(out));
25 | } else {
26 | handler = RDFWriterRegistry.getInstance().get(format).get().getWriter(out);
27 | }
28 | }
29 | return handler;
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/write/RepositoryModelWriter.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.write;
2 |
3 | import java.util.Map;
4 |
5 | import org.eclipse.rdf4j.model.Model;
6 | import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
7 | import org.eclipse.rdf4j.repository.Repository;
8 | import org.eclipse.rdf4j.repository.RepositoryConnection;
9 |
10 | import fr.sparna.rdf.xls2rdf.ModelWriterIfc;
11 | import fr.sparna.rdf.xls2rdf.Xls2RdfException;
12 |
13 | /**
14 | * @author Thomas Francart
15 | *
16 | */
17 | public class RepositoryModelWriter implements ModelWriterIfc {
18 |
19 | private Repository outputRepository;
20 |
21 | public RepositoryModelWriter(Repository outputRepository) {
22 | super();
23 | this.outputRepository = outputRepository;
24 | }
25 |
26 | @Override
27 | public void saveGraphModel(String graph, Model model, Map prefixes, String baseIri) {
28 | try {
29 | try(RepositoryConnection c = this.outputRepository.getConnection()) {
30 | // register the prefixes
31 | prefixes.entrySet().forEach(e -> c.setNamespace(e.getKey(), e.getValue()));
32 | c.add(model, SimpleValueFactory.getInstance().createIRI(graph));
33 | }
34 |
35 | // baseIri cannot be kept here in the outputRepository
36 | } catch(Exception e) {
37 | throw Xls2RdfException.rethrow(e);
38 | }
39 | }
40 |
41 | @Override
42 | public void beginWorkbook() {
43 | // nothing
44 | }
45 |
46 | @Override
47 | public void endWorkbook() {
48 | // nothing
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/java/fr/sparna/rdf/xls2rdf/write/ZipOutputStreamModelWriter.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf.write;
2 |
3 | import java.io.File;
4 | import java.io.FileOutputStream;
5 | import java.io.IOException;
6 | import java.io.OutputStream;
7 | import java.nio.charset.Charset;
8 | import java.net.URLEncoder;
9 | import java.util.Map;
10 | import java.util.zip.ZipEntry;
11 | import java.util.zip.ZipOutputStream;
12 |
13 | import org.eclipse.rdf4j.model.Model;
14 | import org.eclipse.rdf4j.repository.Repository;
15 | import org.eclipse.rdf4j.repository.RepositoryConnection;
16 | import org.eclipse.rdf4j.repository.sail.SailRepository;
17 | import org.eclipse.rdf4j.rio.RDFFormat;
18 | import org.eclipse.rdf4j.rio.RDFHandler;
19 | import org.eclipse.rdf4j.rio.RDFWriterRegistry;
20 | import org.eclipse.rdf4j.rio.helpers.BufferedGroupingRDFHandler;
21 | import org.eclipse.rdf4j.sail.memory.MemoryStore;
22 |
23 | import fr.sparna.rdf.xls2rdf.ModelWriterIfc;
24 | import fr.sparna.rdf.xls2rdf.Xls2RdfException;
25 |
26 | /**
27 | * @author thomas
28 | *
29 | */
30 | public class ZipOutputStreamModelWriter implements ModelWriterIfc {
31 |
32 | private OutputStream underlyingStream;
33 | private ZipOutputStream out;
34 | private RDFFormat format = RDFFormat.RDFXML;
35 | private String graphSuffix = null;
36 | private boolean saveGraphFile = false;
37 |
38 | private boolean grouping = true;
39 |
40 | public ZipOutputStreamModelWriter(ZipOutputStream out) {
41 | super();
42 | this.out = out;
43 | }
44 |
45 | public ZipOutputStreamModelWriter(File f) {
46 | super();
47 | try {
48 | if(!f.exists()) {
49 | f.createNewFile();
50 | }
51 | this.underlyingStream = new FileOutputStream(f);
52 | this.out = new ZipOutputStream(this.underlyingStream, Charset.forName("UTF-8"));
53 | this.out.setLevel(9);
54 | } catch (Exception e) {
55 | throw new RuntimeException(e);
56 | }
57 | }
58 |
59 | public ZipOutputStreamModelWriter(OutputStream underlyingStream) {
60 | super();
61 | try {
62 | this.underlyingStream = underlyingStream;
63 | this.out = new ZipOutputStream(this.underlyingStream, Charset.forName("UTF-8"));
64 | this.out.setLevel(9);
65 | } catch (Exception e) {
66 | throw new RuntimeException(e);
67 | }
68 | }
69 |
70 | /* (non-Javadoc)
71 | * @see fr.sparna.rdf.skos.xls2skos.ModelSaverIfc#saveGraphModel(java.lang.String, org.eclipse.rdf4j.model.Model)
72 | */
73 | @Override
74 | public void saveGraphModel(String graph, Model model, Map prefixes, String baseIri) {
75 | try {
76 | // declare a new ZipEntry in the Zip file
77 | graph = graph + ((this.graphSuffix != null)?graphSuffix:"");
78 |
79 | String entryname = URLEncoder.encode(graph, "UTF-8") + "." + format.getDefaultFileExtension();
80 | // String entryname = graph.substring(graph.lastIndexOf('/')+1) + "." + format.getDefaultFileExtension();
81 | System.out.println(entryname);
82 | out.putNextEntry(new ZipEntry(entryname));
83 |
84 | // writes in the entry
85 | RDFHandler handler = RDFHandlerFactory.buildHandler(grouping, baseIri, format, out);
86 | exportModel(model, handler, prefixes);
87 |
88 | // close the entry
89 | out.closeEntry();
90 |
91 | if(saveGraphFile) {
92 | String graphFileName = entryname + ".graph";
93 | out.putNextEntry(new ZipEntry(graphFileName));
94 | out.write(graph.getBytes());
95 | }
96 |
97 | } catch(Exception e) {
98 | throw Xls2RdfException.rethrow(e);
99 | }
100 | }
101 |
102 | public void exportModel(Model model, RDFHandler handler, Map prefixes) {
103 | Repository r = new SailRepository(new MemoryStore());
104 | r.init();
105 | try(RepositoryConnection c = r.getConnection()) {
106 | // register the prefixes
107 | prefixes.entrySet().forEach(e -> c.setNamespace(e.getKey(), e.getValue()));
108 | c.add(model);
109 | c.export(handler);
110 | }
111 | }
112 |
113 | public String getGraphSuffix() {
114 | return graphSuffix;
115 | }
116 |
117 | public void setGraphSuffix(String graphSuffix) {
118 | this.graphSuffix = graphSuffix;
119 | }
120 |
121 | public boolean isSaveGraphFile() {
122 | return saveGraphFile;
123 | }
124 |
125 | public void setSaveGraphFile(boolean saveGraphFile) {
126 | this.saveGraphFile = saveGraphFile;
127 | }
128 |
129 | public boolean isGrouping() {
130 | return grouping;
131 | }
132 |
133 | public void setGrouping(boolean grouping) {
134 | this.grouping = grouping;
135 | }
136 |
137 | @Override
138 | public void beginWorkbook() {
139 |
140 | }
141 |
142 | @Override
143 | public void endWorkbook() {
144 | try {
145 | out.flush();
146 | out.close();
147 | this.underlyingStream.close();
148 |
149 | } catch (IOException e) {
150 | throw new RuntimeException(e);
151 | }
152 | }
153 |
154 | public RDFFormat getFormat() {
155 | return format;
156 | }
157 |
158 | public void setFormat(RDFFormat format) {
159 | this.format = format;
160 | }
161 |
162 | }
163 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/resources/fr/sparna/rdf/xls2rdf/postprocessing/broaderTransitive.ru:
--------------------------------------------------------------------------------
1 | PREFIX skos:
2 |
3 | insert {
4 | ?child skos:broaderTransitive ?ancestor .
5 | } WHERE {
6 | ?child (skos:broader|^skos:narrower)+ ?ancestor .
7 | }
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/resources/fr/sparna/rdf/xls2rdf/skos2skosxl/S16-URIs.ru:
--------------------------------------------------------------------------------
1 | # S55 : The property chain (skosxl:prefLabel, skosxl:literalForm) is a sub-property of skos:prefLabel.
2 | PREFIX skos:
3 | PREFIX skosxl:
4 | PREFIX rdfs:
5 | PREFIX rdf:
6 |
7 | DELETE {
8 | ?x ?noteProperty ?note
9 | }
10 | INSERT {
11 | ?x ?noteProperty ?noteUri .
12 | ?noteUri rdf:value ?note .
13 | } WHERE {
14 | ?x a skos:Concept .
15 |
16 | # compute how many labels on the same concepts are before this one
17 | {
18 | SELECT ?x ?noteProperty ?note (COUNT(?anotherNoteBefore) AS ?index)
19 | WHERE {
20 | ?x ?noteProperty ?note .
21 | FILTER(isLiteral(?note))
22 | FILTER(?noteProperty IN (skos:definition))
23 | OPTIONAL {
24 | ?x skos:definition ?anotherNoteBefore .
25 | FILTER(STR(?anotherNoteBefore) < STR(?note))
26 | }
27 | } GROUP BY ?x ?noteProperty ?note
28 | }
29 |
30 | BIND(IRI(
31 | CONCAT(
32 | STR(?x),
33 | '-def-',
34 | STR(?index)
35 | )
36 | ) AS ?noteUri)
37 |
38 | }
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/resources/fr/sparna/rdf/xls2rdf/skos2skosxl/S16-bnodes.ru:
--------------------------------------------------------------------------------
1 | # S55 : The property chain (skosxl:prefLabel, skosxl:literalForm) is a sub-property of skos:prefLabel.
2 | PREFIX skos:
3 | PREFIX skosxl:
4 | PREFIX rdfs:
5 | PREFIX rdf:
6 |
7 | DELETE {
8 | ?x ?noteProperty ?note
9 | }
10 | INSERT {
11 | ?x ?noteProperty ?noteUri .
12 | ?noteUri rdf:value ?note .
13 | } WHERE {
14 | ?x a skos:Concept .
15 |
16 | # compute how many labels on the same concepts are before this one
17 | {
18 | SELECT ?x ?noteProperty ?note (COUNT(?anotherNoteBefore) AS ?index)
19 | WHERE {
20 | ?x ?noteProperty ?note .
21 | FILTER(isLiteral(?note))
22 | FILTER(?noteProperty IN (skos:note, skos:changeNote, skos:definition, skos:editorialNote, skos:example, skos:historyNote, skos:scopeNote))
23 | OPTIONAL {
24 | ?x skos:note|skos:changeNote|skos:definition|skos:editorialNote|skos:example|skos:historyNote|skos:scopeNote ?anotherNoteBefore .
25 | FILTER(STR(?anotherNoteBefore) < STR(?note))
26 | }
27 | } GROUP BY ?x ?noteProperty ?note
28 | }
29 |
30 | BIND(BNODE() AS ?noteUri)
31 |
32 | }
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/resources/fr/sparna/rdf/xls2rdf/skos2skosxl/S55-S56-S57-URIs.ru:
--------------------------------------------------------------------------------
1 | # S55 : The property chain (skosxl:prefLabel, skosxl:literalForm) is a sub-property of skos:prefLabel.
2 | PREFIX skos:
3 | PREFIX skosxl:
4 | PREFIX rdfs:
5 | DELETE {
6 | ?x ?labelProperty ?label
7 | }
8 | INSERT {
9 | ?x ?xlLabelProperty ?labelUri .
10 | ?labelUri skosxl:literalForm ?label .
11 | ?labelUri a skosxl:Label .
12 | } WHERE {
13 | # XL-ify Concepts, Collections, ConceptSchemes
14 | { { ?x a skos:Concept . } UNION { ?x a skos:Collection . } UNION { ?x a skos:ConceptScheme . } }
15 |
16 | # compute how many labels on the same concepts are before this one
17 | {
18 | SELECT ?x ?labelProperty ?label (COUNT(?anotherLabelBefore) AS ?index)
19 | WHERE {
20 | ?x ?labelProperty ?label .
21 | FILTER(?labelProperty IN (skos:prefLabel, skos:altLabel, skos:hiddenLabel))
22 | OPTIONAL {
23 | ?x skos:prefLabel|skos:altLabel|skos:hiddenLabel ?anotherLabelBefore .
24 | FILTER(lang(?anotherLabelBefore) = lang(?label))
25 | FILTER(STR(?anotherLabelBefore) < STR(?label))
26 | }
27 | } GROUP BY ?x ?labelProperty ?label
28 | }
29 |
30 | BIND(IRI(
31 | CONCAT(
32 | STR(?x),
33 | '-label-',
34 | lang(?label),
35 | '-',
36 | STR(?index)
37 | )
38 | ) AS ?labelUri)
39 |
40 | BIND(
41 | IF(?labelProperty = skos:prefLabel,
42 | skosxl:prefLabel,
43 | IF(?labelProperty = skos:altLabel,
44 | skosxl:altLabel,
45 | IF(?labelProperty = skos:hiddenLabel,
46 | skosxl:hiddenLabel,
47 | rdfs:label
48 | )
49 | )
50 | )
51 | AS ?xlLabelProperty)
52 | }
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/resources/fr/sparna/rdf/xls2rdf/skos2skosxl/S55-S56-S57-bnodes.ru:
--------------------------------------------------------------------------------
1 | # S55 : The property chain (skosxl:prefLabel, skosxl:literalForm) is a sub-property of skos:prefLabel.
2 | PREFIX skos:
3 | PREFIX skosxl:
4 | PREFIX rdfs:
5 | DELETE {
6 | ?x ?labelProperty ?label
7 | }
8 | INSERT {
9 | ?x ?xlLabelProperty ?labelUri .
10 | ?labelUri skosxl:literalForm ?label .
11 | ?labelUri a skosxl:Label .
12 | } WHERE {
13 | ?x a skos:Concept .
14 |
15 | # compute how many labels on the same concepts are before this one
16 | {
17 | SELECT ?x ?labelProperty ?label (COUNT(?anotherLabelBefore) AS ?index)
18 | WHERE {
19 | ?x ?labelProperty ?label .
20 | FILTER(?labelProperty IN (skos:prefLabel, skos:altLabel, skos:hiddenLabel))
21 | OPTIONAL {
22 | ?x skos:prefLabel|skos:altLabel|skos:hiddenLabel ?anotherLabelBefore .
23 | FILTER(STR(?anotherLabelBefore) < STR(?label))
24 | }
25 | } GROUP BY ?x ?labelProperty ?label
26 | }
27 |
28 | BIND(BNODE() AS ?labelUri)
29 |
30 | BIND(
31 | IF(?labelProperty = skos:prefLabel,
32 | skosxl:prefLabel,
33 | IF(?labelProperty = skos:altLabel,
34 | skosxl:altLabel,
35 | IF(?labelProperty = skos:hiddenLabel,
36 | skosxl:hiddenLabel,
37 | rdfs:label
38 | )
39 | )
40 | )
41 | AS ?xlLabelProperty)
42 | }
--------------------------------------------------------------------------------
/xls2rdf-lib/src/main/resources/logback-xls2rdf.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | %d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n
7 |
8 |
9 |
10 |
11 | xls2rdf.log
12 |
13 |
14 | xls2rdf.%d{yyyy-MM-dd}.log
15 |
16 |
17 | 5
18 |
19 |
20 | %d{HH:mm:ss.SSS} %-4relative %-5level %logger{35} - %msg%n
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/java/fr/sparna/rdf/xls2rdf/ColumnHeaderParserTest.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf;
2 |
3 | import org.eclipse.rdf4j.model.vocabulary.SKOS;
4 | import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
5 | import org.junit.Assert;
6 | import org.junit.Before;
7 | import org.junit.Test;
8 |
9 | import fr.sparna.rdf.xls2rdf.ColumnHeader;
10 | import fr.sparna.rdf.xls2rdf.ColumnHeaderParser;
11 | import fr.sparna.rdf.xls2rdf.PrefixManager;
12 |
13 | public class ColumnHeaderParserTest {
14 |
15 | private ColumnHeaderParser parser;
16 | private PrefixManager prefixManager;
17 |
18 | @Before
19 | public void before() {
20 | this.prefixManager = new PrefixManager();
21 | this.prefixManager.register("skos", SKOS.NAMESPACE);
22 | this.prefixManager.register("xsd", XMLSchema.NAMESPACE);
23 | parser = new ColumnHeaderParser(this.prefixManager);
24 | }
25 |
26 | @Test
27 | public void test1() {
28 | String TEST = "http://www.w3.org/2004/02/skos/core#prefLabel";
29 | ColumnHeader header = this.parser.parse(TEST, null);
30 | Assert.assertTrue(header.getDeclaredProperty().equals(SKOS.PREF_LABEL.toString()));
31 | }
32 |
33 | @Test
34 | public void test2() {
35 | String TEST = "skos:prefLabel";
36 | ColumnHeader header = this.parser.parse(TEST, null);
37 | Assert.assertTrue(header.getDeclaredProperty().equals(TEST));
38 | Assert.assertTrue(header.getProperty().toString().equals(SKOS.PREF_LABEL.toString()));
39 | }
40 |
41 | @Test
42 | public void test3() {
43 | String TEST = "skos:prefLabel@en";
44 | ColumnHeader header = this.parser.parse(TEST, null);
45 | // System.out.println(header);
46 | Assert.assertTrue(header.getDeclaredProperty().equals("skos:prefLabel"));
47 | Assert.assertTrue(header.getProperty().toString().equals(SKOS.PREF_LABEL.toString()));
48 | Assert.assertTrue(header.getLanguage().get().equals("en"));
49 | }
50 |
51 | @Test
52 | public void test4() {
53 | String TEST = "skos:prefLabel^^xsd:date";
54 | ColumnHeader header = this.parser.parse(TEST, null);
55 | // System.out.println(header);
56 | Assert.assertTrue(header.getDeclaredProperty().equals("skos:prefLabel"));
57 | Assert.assertTrue(header.getProperty().toString().equals(SKOS.PREF_LABEL.toString()));
58 | Assert.assertTrue(header.getDatatype().get().equals(XMLSchema.DATE));
59 | }
60 |
61 | @Test
62 | public void test5() {
63 | String TEST = "skos:prefLabel^^";
64 | ColumnHeader header = this.parser.parse(TEST, null);
65 | // System.out.println(header);
66 | Assert.assertTrue(header.getDeclaredProperty().equals("skos:prefLabel"));
67 | Assert.assertTrue(header.getProperty().toString().equals(SKOS.PREF_LABEL.toString()));
68 | Assert.assertTrue(header.getDatatype().get().equals(XMLSchema.DATE));
69 | }
70 |
71 | @Test
72 | public void test6() {
73 | String TEST = "http://www.w3.org/2004/02/skos/core#prefLabel^^";
74 | ColumnHeader header = this.parser.parse(TEST, null);
75 | // System.out.println(header);
76 | Assert.assertTrue(header.getDeclaredProperty().equals("http://www.w3.org/2004/02/skos/core#prefLabel"));
77 | Assert.assertTrue(header.getProperty().toString().equals(SKOS.PREF_LABEL.toString()));
78 | Assert.assertTrue(header.getDatatype().get().equals(XMLSchema.DATE));
79 | Assert.assertTrue(header.getParameters().isEmpty());
80 | }
81 |
82 | @Test
83 | public void test10() {
84 | String TEST = "skos:prefLabel(separator=\",\")";
85 | ColumnHeader header = this.parser.parse(TEST, null);
86 | // System.out.println(header);
87 | Assert.assertTrue(header.getDeclaredProperty().equals("skos:prefLabel"));
88 | Assert.assertTrue(header.getProperty().toString().equals(SKOS.PREF_LABEL.toString()));
89 | Assert.assertTrue(!header.getDatatype().isPresent());
90 | Assert.assertTrue(!header.getLanguage().isPresent());
91 | Assert.assertTrue(header.getParameters().get("separator").equals(","));
92 | }
93 |
94 | @Test
95 | public void test11() {
96 | String TEST = "skos:prefLabel@en(separator=\",\")";
97 | ColumnHeader header = this.parser.parse(TEST, null);
98 | // System.out.println(header);
99 | Assert.assertTrue(header.getDeclaredProperty().equals("skos:prefLabel"));
100 | Assert.assertTrue(header.getProperty().toString().equals(SKOS.PREF_LABEL.toString()));
101 | Assert.assertTrue(!header.getDatatype().isPresent());
102 | Assert.assertTrue(header.getLanguage().get().equals("en"));
103 | Assert.assertTrue(header.getParameters().get("separator").equals(","));
104 | }
105 |
106 | @Test
107 | public void test12() {
108 | String TEST = "skos:prefLabel^^xsd:date(separator=\",\")";
109 | ColumnHeader header = this.parser.parse(TEST, null);
110 | // System.out.println(header);
111 | Assert.assertTrue(header.getDeclaredProperty().equals("skos:prefLabel"));
112 | Assert.assertTrue(header.getProperty().toString().equals(SKOS.PREF_LABEL.toString()));
113 | Assert.assertTrue(header.getDatatype().get().equals(XMLSchema.DATE));
114 | Assert.assertTrue(!header.getLanguage().isPresent());
115 | Assert.assertTrue(header.getParameters().get("separator").equals(","));
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/java/fr/sparna/rdf/xls2rdf/FormatsTest.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf;
2 |
3 | import org.eclipse.rdf4j.repository.Repository;
4 | import org.eclipse.rdf4j.repository.sail.SailRepository;
5 | import org.eclipse.rdf4j.sail.memory.MemoryStore;
6 | import org.junit.Before;
7 | import org.junit.Test;
8 |
9 | import fr.sparna.rdf.xls2rdf.listen.ListXls2RdfMessageListener;
10 | import fr.sparna.rdf.xls2rdf.postprocess.SkosPostProcessor;
11 | import fr.sparna.rdf.xls2rdf.write.RepositoryModelWriter;
12 |
13 | import java.io.File;
14 | import java.util.Collections;
15 |
16 | public class FormatsTest {
17 |
18 | protected Xls2RdfConverter converter;
19 | private Repository outputRepository;
20 | private ListXls2RdfMessageListener messageListener;
21 |
22 | @Before
23 | public void before() {
24 | this.outputRepository = new SailRepository(new MemoryStore());
25 | this.outputRepository.init();
26 |
27 | this.converter = new Xls2RdfConverter(new RepositoryModelWriter(outputRepository), "fr");
28 | this.converter.setPostProcessors(Collections.singletonList(new SkosPostProcessor(false)));
29 | this.messageListener = new ListXls2RdfMessageListener();
30 | this.converter.setMessageListener(messageListener);
31 | }
32 |
33 | @Test
34 | public void test_formatsTest() {
35 | File testFolder = new File("src/test/resources/suite/_30_formatsTest");
36 | File input = new File(testFolder, "input.xls");
37 | if(!input.exists()) {
38 | input = new File(testFolder, "input.xlsx");
39 | }
40 | if(!input.exists()) {
41 | input = new File(testFolder, "input.xlsm");
42 | }
43 |
44 | // convert
45 | this.converter.processFile(input);
46 |
47 | System.out.println(this.messageListener.getMessages());
48 | }
49 |
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/java/fr/sparna/rdf/xls2rdf/SimpleInvalidPropertyListValidator.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf;
2 |
3 | import java.util.List;
4 | import java.util.function.Predicate;
5 |
6 | import org.eclipse.rdf4j.model.IRI;
7 |
8 | public class SimpleInvalidPropertyListValidator implements Predicate {
9 |
10 | protected List invalidProperties;
11 |
12 | public SimpleInvalidPropertyListValidator(List invalidProperties) {
13 | super();
14 | this.invalidProperties = invalidProperties;
15 | }
16 |
17 | @Override
18 | public boolean test(IRI propertyIRI) {
19 | return !this.invalidProperties.contains(propertyIRI);
20 | }
21 |
22 | }
23 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/java/fr/sparna/rdf/xls2rdf/ValueProcessorTest.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf;
2 |
3 | import org.eclipse.rdf4j.model.Model;
4 | import org.eclipse.rdf4j.model.Resource;
5 | import org.eclipse.rdf4j.model.impl.LinkedHashModelFactory;
6 | import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
7 | import org.eclipse.rdf4j.model.vocabulary.SKOS;
8 | import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
9 | import org.junit.Before;
10 | import org.junit.Test;
11 |
12 | import fr.sparna.rdf.xls2rdf.ColumnHeaderParser;
13 | import fr.sparna.rdf.xls2rdf.PrefixManager;
14 | import fr.sparna.rdf.xls2rdf.ValueProcessorFactory;
15 | import fr.sparna.rdf.xls2rdf.ValueProcessorIfc;
16 | import fr.sparna.rdf.xls2rdf.listen.LogXls2RdfMessageListener;
17 | import junit.framework.Assert;
18 |
19 | public class ValueProcessorTest {
20 |
21 | private SimpleValueFactory vf = SimpleValueFactory.getInstance();
22 | private Resource subject;
23 | private Model model;
24 |
25 | private ColumnHeaderParser parser;
26 | private PrefixManager prefixManager;
27 |
28 | private ValueProcessorFactory factory;
29 |
30 |
31 | @Before
32 | public void before() {
33 | this.subject = vf.createIRI("http://sparna.fr");
34 | this.model = new LinkedHashModelFactory().createEmptyModel();
35 |
36 | this.prefixManager = new PrefixManager();
37 | this.prefixManager.register("skos", SKOS.NAMESPACE);
38 | this.prefixManager.register("xsd", XMLSchema.NAMESPACE);
39 | parser = new ColumnHeaderParser(this.prefixManager);
40 |
41 | factory = new ValueProcessorFactory(new LogXls2RdfMessageListener());
42 | }
43 |
44 | @Test
45 | public void plainLiteralTest() {
46 | ValueProcessorIfc vg = factory.plainLiteral(SKOS.NOTATION);
47 | vg.processValue(model, subject, "1", null, null);
48 | Assert.assertTrue(model.contains(subject, SKOS.NOTATION, vf.createLiteral("1")));
49 | }
50 |
51 | @Test
52 | public void langOrPlainLiteralTest() {
53 | ValueProcessorIfc vg = factory.langOrPlainLiteral(SKOS.PREF_LABEL);
54 | vg.processValue(model, subject, "sparna", null, null);
55 | vg.processValue(model, subject, "SPARNA", null, "fr");
56 | Assert.assertTrue(model.contains(subject, SKOS.PREF_LABEL, vf.createLiteral("sparna")));
57 | Assert.assertTrue(model.contains(subject, SKOS.PREF_LABEL, vf.createLiteral("SPARNA", "fr")));
58 | }
59 |
60 | @Test
61 | public void resourceOrLiteralTest() {
62 | ValueProcessorIfc vg = factory.resourceOrLiteral(this.parser.parse("skos:prefLabel^^xsd:string", null), prefixManager);
63 | vg.processValue(model, subject, "sparna", null, "fr");
64 | Assert.assertTrue(model.contains(subject, SKOS.PREF_LABEL, vf.createLiteral("sparna", XMLSchema.STRING)));
65 | }
66 |
67 | @Test
68 | public void overwriteLangTest() {
69 | ValueProcessorIfc vg = factory.resourceOrLiteral(this.parser.parse("skos:prefLabel@en", null), prefixManager);
70 | vg.processValue(model, subject, "sparna", null, "fr");
71 | Assert.assertTrue(model.contains(subject, SKOS.PREF_LABEL, vf.createLiteral("sparna", "fr")));
72 | }
73 |
74 | @Test
75 | public void splitLangLiteralTest() {
76 | ValueProcessorIfc vg = factory.split(
77 | factory.resourceOrLiteral(this.parser.parse("skos:altLabel", null), prefixManager),
78 | ","
79 | );
80 | vg.processValue(model, subject, "sparna, SPARNA", null, "fr");
81 | Assert.assertTrue(model.contains(subject, SKOS.ALT_LABEL, vf.createLiteral("sparna", "fr")));
82 | Assert.assertTrue(model.contains(subject, SKOS.ALT_LABEL, vf.createLiteral("SPARNA", "fr")));
83 | }
84 |
85 | @Test
86 | public void splitDatatypeLiteralTest() {
87 | ValueProcessorIfc vg = factory.split(
88 | factory.resourceOrLiteral(this.parser.parse("skos:altLabel^^xsd:string", null), prefixManager),
89 | ","
90 | );
91 | vg.processValue(model, subject, "sparna, SPARNA", null, "fr");
92 | Assert.assertTrue(model.contains(subject, SKOS.ALT_LABEL, vf.createLiteral("sparna", XMLSchema.STRING)));
93 | Assert.assertTrue(model.contains(subject, SKOS.ALT_LABEL, vf.createLiteral("SPARNA", XMLSchema.STRING)));
94 | }
95 |
96 | @Test
97 | public void splitFullUriTest() {
98 | ValueProcessorIfc vg = factory.split(
99 | factory.resourceOrLiteral(this.parser.parse("skos:exactMatch", null), prefixManager),
100 | ","
101 | );
102 | vg.processValue(model, subject, "http://blog.sparna.fr, http://SPARNA.fr", null, "fr");
103 | Assert.assertTrue(model.contains(subject, SKOS.EXACT_MATCH, vf.createIRI("http://blog.sparna.fr")));
104 | Assert.assertTrue(model.contains(subject, SKOS.EXACT_MATCH, vf.createIRI("http://SPARNA.fr")));
105 | }
106 |
107 | @Test
108 | public void splitPrefixedUriTest() {
109 | ValueProcessorIfc vg = factory.split(
110 | factory.resourceOrLiteral(this.parser.parse("skos:exactMatch", null), prefixManager),
111 | ","
112 | );
113 | vg.processValue(model, subject, "skos:notation, skos:prefLabel", null, "fr");
114 | Assert.assertTrue(model.contains(subject, SKOS.EXACT_MATCH, SKOS.PREF_LABEL));
115 | Assert.assertTrue(model.contains(subject, SKOS.EXACT_MATCH, SKOS.NOTATION));
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/java/fr/sparna/rdf/xls2rdf/Xls2RdfConverterTest.java:
--------------------------------------------------------------------------------
1 | package fr.sparna.rdf.xls2rdf;
2 |
3 | import java.io.File;
4 | import java.util.Arrays;
5 | import java.util.Collections;
6 | import java.util.List;
7 |
8 | import org.junit.runner.RunWith;
9 | import org.junit.runners.AllTests;
10 |
11 | import junit.framework.TestSuite;
12 |
13 | /**
14 | * Don't rename this class , it has to end with *Test to be picked up my Maven surfefire plugin
15 | *
16 | */
17 | @RunWith(AllTests.class)
18 | public class Xls2RdfConverterTest {
19 |
20 | public static TestSuite suite() {
21 | TestSuite ts = new TestSuite();
22 |
23 | File testDir = new File("src/test/resources/suite");
24 | List sortedList = Arrays.asList(testDir.listFiles());
25 | Collections.sort(sortedList);
26 | for (File aDir : sortedList) {
27 | if(aDir.isDirectory()) {
28 | ts.addTest(new Xls2RdfConverterTestExecution(aDir));
29 | }
30 | }
31 |
32 |
33 | return ts;
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/.gitignore:
--------------------------------------------------------------------------------
1 | */output.ttl
2 | */output.trig
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_00_simple/.gitignore:
--------------------------------------------------------------------------------
1 | /output.ttl
2 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_00_simple/expected.ttl:
--------------------------------------------------------------------------------
1 | @prefix rdf: .
2 | @prefix rdfs: .
3 | @prefix owl: .
4 | @prefix dcterms: .
5 | @prefix xsd: .
6 | @prefix skos: .
7 | @prefix test: .
8 |
9 | a skos:ConceptScheme ;
10 | skos:hasTopConcept test:concept_1;
11 | .
12 |
13 | test:concept_1 a skos:Concept ;
14 | skos:prefLabel "Test"@fr;
15 | skos:altLabel "toto"@fr;
16 | skos:inScheme ;
17 | skos:topConceptOf ;
18 | .
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_00_simple/input.xls:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparna-git/xls2rdf/a7b6e173b300b8b4029b3eab93fb55689a2e849d/xls2rdf-lib/src/test/resources/suite/_00_simple/input.xls
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_01_exemple1/.gitignore:
--------------------------------------------------------------------------------
1 | /output.ttl
2 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_01_exemple1/expected.ttl:
--------------------------------------------------------------------------------
1 | @prefix dct: .
2 | @prefix rdf: .
3 | @prefix skos: .
4 |
5 | a skos:ConceptScheme;
6 | dct:description "The days of the week"@fr;
7 | dct:title "Weekdays"@fr;
8 | skos:hasTopConcept , ,
9 | , ,
10 | , .
11 |
12 | a skos:Concept;
13 | skos:definition "The day where you get back at work"@fr;
14 | skos:inScheme ;
15 | skos:notation "MON"@fr;
16 | skos:prefLabel "Monday"@fr;
17 | skos:topConceptOf .
18 |
19 | a skos:Concept;
20 | skos:definition "The most productive day of the week."@fr;
21 | skos:inScheme ;
22 | skos:notation "TUE"@fr;
23 | skos:prefLabel "Tuesday"@fr;
24 | skos:topConceptOf .
25 |
26 | a skos:Concept;
27 | skos:inScheme ;
28 | skos:notation "WED"@fr;
29 | skos:prefLabel "Wednesday"@fr;
30 | skos:topConceptOf .
31 |
32 | a skos:Concept;
33 | skos:inScheme ;
34 | skos:notation "THU"@fr;
35 | skos:prefLabel "Thursday"@fr;
36 | skos:topConceptOf .
37 |
38 | a skos:Concept;
39 | skos:definition "Week-end soon !"@fr;
40 | skos:inScheme ;
41 | skos:notation "FRI"@fr;
42 | skos:prefLabel "Friday"@fr;
43 | skos:topConceptOf .
44 |
45 | a skos:Concept;
46 | skos:broader ;
47 | skos:inScheme ;
48 | skos:notation "SAT"@fr;
49 | skos:prefLabel "Saturday"@fr .
50 |
51 | a skos:Concept;
52 | skos:broader ;
53 | skos:definition "The day you sleep."@fr;
54 | skos:inScheme ;
55 | skos:notation "SUN"@fr;
56 | skos:prefLabel "Sunday"@fr .
57 |
58 | a skos:Concept;
59 | skos:definition "Any day of the week-end"@fr;
60 | skos:inScheme ;
61 | skos:narrower , ;
62 | skos:notation "WKND"@fr;
63 | skos:prefLabel "Week-end"@fr;
64 | skos:topConceptOf .
65 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_01_exemple1/input.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparna-git/xls2rdf/a7b6e173b300b8b4029b3eab93fb55689a2e849d/xls2rdf-lib/src/test/resources/suite/_01_exemple1/input.xlsx
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_02_prefixes/.gitignore:
--------------------------------------------------------------------------------
1 | /output.ttl
2 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_02_prefixes/expected.ttl:
--------------------------------------------------------------------------------
1 | @prefix concept-status: .
2 | @prefix days: .
3 | @prefix dct: .
4 | @prefix euvoc: .
5 | @prefix rdf: .
6 | @prefix skos: .
7 |
8 | a skos:ConceptScheme;
9 | dct:description "The days of the week"@fr;
10 | dct:title "Weekdays"@fr;
11 | skos:hasTopConcept days:friday, days:monday, days:thursday, days:tuesday, days:wednesday,
12 | days:week-end .
13 |
14 | days:monday a skos:Concept;
15 | euvoc:status concept-status:CURRENT;
16 | skos:definition "The day where you get back at work"@fr;
17 | skos:inScheme ;
18 | skos:notation "MON"@fr;
19 | skos:prefLabel "Monday"@fr;
20 | skos:topConceptOf .
21 |
22 | days:tuesday a skos:Concept;
23 | euvoc:status concept-status:CURRENT;
24 | skos:definition "The most productive day of the week."@fr;
25 | skos:inScheme ;
26 | skos:notation "TUE"@fr;
27 | skos:prefLabel "Tuesday"@fr;
28 | skos:topConceptOf .
29 |
30 | days:wednesday a skos:Concept;
31 | euvoc:status concept-status:CURRENT;
32 | skos:inScheme ;
33 | skos:notation "WED"@fr;
34 | skos:prefLabel "Wednesday"@fr;
35 | skos:topConceptOf .
36 |
37 | days:thursday a skos:Concept;
38 | euvoc:status concept-status:CURRENT;
39 | skos:inScheme ;
40 | skos:notation "THU"@fr;
41 | skos:prefLabel "Thursday"@fr;
42 | skos:topConceptOf .
43 |
44 | days:friday a skos:Concept;
45 | euvoc:status concept-status:CURRENT;
46 | skos:definition "Week-end soon !"@fr;
47 | skos:inScheme ;
48 | skos:notation "FRI"@fr;
49 | skos:prefLabel "Friday"@fr;
50 | skos:topConceptOf .
51 |
52 | days:saturday a skos:Concept;
53 | euvoc:status concept-status:CURRENT;
54 | skos:broader days:week-end;
55 | skos:inScheme ;
56 | skos:notation "SAT"@fr;
57 | skos:prefLabel "Saturday"@fr .
58 |
59 | days:sunday a skos:Concept;
60 | euvoc:comment "Note that some consider Sunday to be the first day of the week. Should we give ordering numbers to weekdays ?"@fr;
61 | euvoc:status concept-status:CURRENT;
62 | skos:broader days:week-end;
63 | skos:definition "The day you sleep."@fr;
64 | skos:inScheme ;
65 | skos:notation "SUN"@fr;
66 | skos:prefLabel "Sunday"@fr .
67 |
68 | days:week-end a skos:Concept;
69 | euvoc:comment "Check with Andrew if the concept of Week-end is the same in the US, in China and the UK. Try to determine a universal notion of what a \"week-end\" is."@fr;
70 | euvoc:status concept-status:TESTING;
71 | skos:definition "Any day of the week-end"@fr;
72 | skos:inScheme ;
73 | skos:narrower days:saturday, days:sunday;
74 | skos:notation "WKND"@fr;
75 | skos:prefLabel "Week-end"@fr;
76 | skos:topConceptOf .
77 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_02_prefixes/input.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparna-git/xls2rdf/a7b6e173b300b8b4029b3eab93fb55689a2e849d/xls2rdf-lib/src/test/resources/suite/_02_prefixes/input.xlsx
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_03_multilingual/.gitignore:
--------------------------------------------------------------------------------
1 | /output.ttl
2 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_03_multilingual/expected.ttl:
--------------------------------------------------------------------------------
1 | @prefix days: .
2 | @prefix dct: .
3 | @prefix rdf: .
4 | @prefix skos: .
5 |
6 | a skos:ConceptScheme;
7 | dct:description "Les jours de la semaine"@fr, "The days of the week"@en;
8 | dct:title "La semaine"@fr, "Weekdays"@en;
9 | skos:hasTopConcept days:friday, days:monday, days:saturday, days:sunday, days:thursday,
10 | days:tuesday, days:wednesday .
11 |
12 | days:monday a skos:Concept;
13 | skos:altLabel "1"@en, "mon"@en;
14 | skos:inScheme ;
15 | skos:prefLabel "Lundi"@fr, "Monday"@en;
16 | skos:topConceptOf .
17 |
18 | days:tuesday a skos:Concept;
19 | skos:altLabel "2"@en, "tue"@en;
20 | skos:inScheme ;
21 | skos:prefLabel "Mardi"@fr, "Tuesday"@en;
22 | skos:topConceptOf .
23 |
24 | days:wednesday a skos:Concept;
25 | skos:altLabel "3"@en, "wed"@en;
26 | skos:inScheme ;
27 | skos:prefLabel "Mercredi"@fr, "Wednesday"@en;
28 | skos:topConceptOf .
29 |
30 | days:thursday a skos:Concept;
31 | skos:altLabel "4"@en, "thu"@en;
32 | skos:inScheme ;
33 | skos:prefLabel "Jeudi"@fr, "Thursday"@en;
34 | skos:topConceptOf .
35 |
36 | days:friday a skos:Concept;
37 | skos:altLabel "5"@en, "fri"@en;
38 | skos:inScheme ;
39 | skos:prefLabel "Friday"@en, "Vendredi"@fr;
40 | skos:topConceptOf .
41 |
42 | days:saturday a skos:Concept;
43 | skos:altLabel "6"@en, "sat"@en;
44 | skos:inScheme ;
45 | skos:prefLabel "Samedi"@fr, "Saturday"@en;
46 | skos:topConceptOf .
47 |
48 | days:sunday a skos:Concept;
49 | skos:altLabel "7"@en, "sun"@en;
50 | skos:inScheme ;
51 | skos:prefLabel "Dimanche"@fr, "Sunday"@en;
52 | skos:topConceptOf .
53 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_03_multilingual/input.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparna-git/xls2rdf/a7b6e173b300b8b4029b3eab93fb55689a2e849d/xls2rdf-lib/src/test/resources/suite/_03_multilingual/input.xlsx
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_04_datatypes_multiple_sheets/.gitignore:
--------------------------------------------------------------------------------
1 | /output.ttl
2 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_04_datatypes_multiple_sheets/expected.ttl:
--------------------------------------------------------------------------------
1 | @prefix places: .
2 | @prefix rdf: .
3 | @prefix rdfs: .
4 | @prefix schema: .
5 | @prefix xsd: .
6 |
7 | a schema:Event;
8 | schema:location places:Paris;
9 | schema:startDate "2016-11-21"^^xsd:date;
10 | rdfs:label "Semweb.pro"@en, "Semweb.pro"@fr .
11 |
12 | a schema:Event;
13 | schema:location places:Heraklion;
14 | schema:startDate "2016-05-29"^^xsd:date;
15 | rdfs:label "ESWC"@en, "ESWC"@fr .
16 |
17 | places:Paris a schema:Place;
18 | rdfs:label "Paris"@en, "Paris"@fr .
19 |
20 | places:Heraklion a schema:Place;
21 | rdfs:label "Heraklion"@en, "Heraklion"@fr .
22 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_04_datatypes_multiple_sheets/input.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparna-git/xls2rdf/a7b6e173b300b8b4029b3eab93fb55689a2e849d/xls2rdf-lib/src/test/resources/suite/_04_datatypes_multiple_sheets/input.xlsx
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_05_Collections_inverse/.gitignore:
--------------------------------------------------------------------------------
1 | /output.ttl
2 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_05_Collections_inverse/expected.ttl:
--------------------------------------------------------------------------------
1 | @prefix days: .
2 | @prefix dct: .
3 | @prefix rdf: .
4 | @prefix skos: .
5 |
6 | a skos:ConceptScheme;
7 | dct:description "The days of the week"@fr;
8 | dct:title "Weekdays"@fr;
9 | skos:hasTopConcept days:friday, days:monday, days:saturday, days:sunday, days:thursday,
10 | days:tuesday, days:wednesday .
11 |
12 | days:monday a skos:Concept;
13 | skos:inScheme ;
14 | skos:notation "MON"@fr;
15 | skos:prefLabel "Monday"@fr;
16 | skos:topConceptOf .
17 |
18 | days:tuesday a skos:Concept;
19 | skos:inScheme ;
20 | skos:notation "TUE"@fr;
21 | skos:prefLabel "Tuesday"@fr;
22 | skos:topConceptOf .
23 |
24 | days:wednesday a skos:Concept;
25 | skos:inScheme ;
26 | skos:notation "WED"@fr;
27 | skos:prefLabel "Wednesday"@fr;
28 | skos:topConceptOf .
29 |
30 | days:thursday a skos:Concept;
31 | skos:inScheme ;
32 | skos:notation "THU"@fr;
33 | skos:prefLabel "Thursday"@fr;
34 | skos:topConceptOf .
35 |
36 | days:friday a skos:Concept;
37 | skos:inScheme ;
38 | skos:notation "FRI"@fr;
39 | skos:prefLabel "Friday"@fr;
40 | skos:topConceptOf .
41 |
42 | days:saturday a skos:Concept;
43 | skos:inScheme ;
44 | skos:notation "SAT"@fr;
45 | skos:prefLabel "Saturday"@fr;
46 | skos:topConceptOf .
47 |
48 | days:week-end a skos:Collection;
49 | skos:inScheme ;
50 | skos:member days:saturday, days:sunday;
51 | skos:notation "WKND"@fr;
52 | skos:prefLabel "Week-end"@fr .
53 |
54 | days:sunday a skos:Concept;
55 | skos:inScheme ;
56 | skos:notation "SUN"@fr;
57 | skos:prefLabel "Sunday"@fr;
58 | skos:topConceptOf .
59 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_05_Collections_inverse/input.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparna-git/xls2rdf/a7b6e173b300b8b4029b3eab93fb55689a2e849d/xls2rdf-lib/src/test/resources/suite/_05_Collections_inverse/input.xlsx
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_06_OrderedCollections_rdfLists/.gitignore:
--------------------------------------------------------------------------------
1 | /output.ttl
2 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_06_OrderedCollections_rdfLists/expected.ttl:
--------------------------------------------------------------------------------
1 | @prefix days: .
2 | @prefix dct: .
3 | @prefix rdf: .
4 | @prefix skos: .
5 |
6 | a skos:ConceptScheme;
7 | dct:description "The days of the week"@fr;
8 | dct:title "Weekdays"@fr;
9 | skos:hasTopConcept days:friday, days:monday, days:saturday, days:sunday, days:thursday,
10 | days:tuesday, days:wednesday .
11 |
12 | days:monday a skos:Concept;
13 | skos:inScheme ;
14 | skos:prefLabel "Monday"@fr;
15 | skos:topConceptOf .
16 |
17 | days:tuesday a skos:Concept;
18 | skos:inScheme ;
19 | skos:prefLabel "Tuesday"@fr;
20 | skos:topConceptOf .
21 |
22 | days:wednesday a skos:Concept;
23 | skos:inScheme ;
24 | skos:prefLabel "Wednesday"@fr;
25 | skos:topConceptOf .
26 |
27 | days:thursday a skos:Concept;
28 | skos:inScheme ;
29 | skos:prefLabel "Thursday"@fr;
30 | skos:topConceptOf .
31 |
32 | days:friday a skos:Concept;
33 | skos:inScheme ;
34 | skos:prefLabel "Friday"@fr;
35 | skos:topConceptOf .
36 |
37 | days:week-end a skos:OrderedCollection;
38 | skos:inScheme ;
39 | skos:memberList _:node1dka20a80x3178 .
40 |
41 | _:node1dka20a80x3178 rdf:first days:saturday;
42 | rdf:rest _:node1dka20a80x3179 .
43 |
44 | _:node1dka20a80x3179 rdf:first days:sunday;
45 | rdf:rest rdf:nil .
46 |
47 | days:week-end skos:prefLabel "Week-end"@fr .
48 |
49 | days:saturday a skos:Concept;
50 | skos:inScheme ;
51 | skos:prefLabel "Saturday"@fr;
52 | skos:topConceptOf .
53 |
54 | days:sunday a skos:Concept;
55 | skos:inScheme ;
56 | skos:prefLabel "Sunday"@fr;
57 | skos:topConceptOf .
58 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_06_OrderedCollections_rdfLists/input.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparna-git/xls2rdf/a7b6e173b300b8b4029b3eab93fb55689a2e849d/xls2rdf-lib/src/test/resources/suite/_06_OrderedCollections_rdfLists/input.xlsx
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_07_subjectColumn/.gitignore:
--------------------------------------------------------------------------------
1 | /output.ttl
2 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_07_subjectColumn/expected.ttl:
--------------------------------------------------------------------------------
1 | @prefix dbpedia-fr: .
2 | @prefix dbpedia-owl: .
3 | @prefix dct: .
4 | @prefix rdf: .
5 | @prefix schema: .
6 |
7 | dct:title "Paintings"@fr .
8 |
9 | dbpedia-fr:La_Joconde a dbpedia-owl:Artist, dbpedia-owl:Painting;
10 | dbpedia-owl:author dbpedia-fr:L%C3%A9onard_de_Vinci;
11 | schema:name "La Joconde"@fr .
12 |
13 | dbpedia-fr:L%C3%A9onard_de_Vinci schema:name "Léonard de Vinci"@fr .
14 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_07_subjectColumn/input.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparna-git/xls2rdf/a7b6e173b300b8b4029b3eab93fb55689a2e849d/xls2rdf-lib/src/test/resources/suite/_07_subjectColumn/input.xlsx
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_08_lookupColumn/.gitignore:
--------------------------------------------------------------------------------
1 | /output.ttl
2 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_08_lookupColumn/expected.ttl:
--------------------------------------------------------------------------------
1 | @prefix days: .
2 | @prefix dct: .
3 | @prefix rdf: .
4 | @prefix skos: .
5 |
6 | a skos:ConceptScheme;
7 | dct:title "Week days"@fr;
8 | skos:hasTopConcept days:Sunday, days:WeekEnd, days:WorkingDay .
9 |
10 | days:Monday a skos:Concept;
11 | skos:broader days:WorkingDay;
12 | skos:inScheme ;
13 | skos:prefLabel "Monday"@en .
14 |
15 | days:Tuesday a skos:Concept;
16 | skos:broader days:WorkingDay;
17 | skos:inScheme ;
18 | skos:prefLabel "Tuesday"@en .
19 |
20 | days:Wednesday a skos:Concept;
21 | skos:broader days:WorkingDay;
22 | skos:inScheme ;
23 | skos:prefLabel "Wednesday"@en .
24 |
25 | days:Thursday a skos:Concept;
26 | skos:broader days:WorkingDay;
27 | skos:inScheme ;
28 | skos:prefLabel "Thursday"@en .
29 |
30 | days:Friday a skos:Concept;
31 | skos:broader days:WorkingDay;
32 | skos:inScheme ;
33 | skos:prefLabel "Friday"@en .
34 |
35 | days:Saturday a skos:Concept;
36 | skos:broader days:WeekEnd;
37 | skos:inScheme ;
38 | skos:prefLabel "Saturday"@en .
39 |
40 | days:Sunday a skos:Concept;
41 | skos:inScheme ;
42 | skos:prefLabel "Sunday"@en;
43 | skos:topConceptOf .
44 |
45 | days:WeekEnd a skos:Concept;
46 | skos:inScheme ;
47 | skos:narrower days:Saturday;
48 | skos:prefLabel "Week-end"@en;
49 | skos:topConceptOf .
50 |
51 | days:WorkingDay a skos:Concept;
52 | skos:inScheme ;
53 | skos:narrower days:Friday, days:Monday, days:Thursday, days:Tuesday, days:Wednesday;
54 | skos:prefLabel "Working day"@en;
55 | skos:topConceptOf .
56 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_08_lookupColumn/input.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sparna-git/xls2rdf/a7b6e173b300b8b4029b3eab93fb55689a2e849d/xls2rdf-lib/src/test/resources/suite/_08_lookupColumn/input.xlsx
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_10_macro/.gitignore:
--------------------------------------------------------------------------------
1 | /output.ttl
2 |
--------------------------------------------------------------------------------
/xls2rdf-lib/src/test/resources/suite/_10_macro/expected.ttl:
--------------------------------------------------------------------------------
1 | @prefix dct: