Difference between revisions of "SIG:GraphTechnologies"

From TEIWiki
Jump to navigation Jump to search
Line 36: Line 36:
  
 
The next step is to export the data with some [[cypher]] to the Standoff-Property JSON-Format.
 
The next step is to export the data with some [[cypher]] to the Standoff-Property JSON-Format.
 +
 +
<code>
 +
// Export TEI-Graph to Standoff-Property-JSON-Format by Stefan Armbruster
 +
match path=(d:XmlDocument)-[:NE*]->(e:XmlCharacters)
 +
where not (e)-[:NE]->()
 +
with tail(nodes(path)) as words, d
 +
with reduce(s="", x in words| s + x.text ) as allText, d
 +
call apoc.path.expandConfig(d,{
 +
relationshipFilter: '<IS_CHILD_OF',
 +
labelFilter: 'XmlTag',
 +
bfs: false,
 +
minLevel: 1
 +
}) yield path
 +
with allText, path, nodes(path)[-1] as this
 +
MATCH p=(this)-[:NEXT*]->(x)
 +
where (x)-[:LAST_CHILD_OF*]->(this) and any(x in nodes(p) WHERE x:XmlCharacters)
 +
with allText, this, collect(p)[-1] as longest
 +
with allText, this, [x in nodes(longest) where x:XmlCharacters] as xmlCharacters
 +
with allText, this,
 +
apoc.coll.min([x in xmlCharacters | x.startIndex]) as min,
 +
apoc.coll.max([x in xmlCharacters | x.endIndex]) as max,
 +
apoc.text.join([x in xmlCharacters | x.text], "") as text
 +
with allText, {
 +
index:id(this),
 +
startIndex: min,
 +
endIndex: max,
 +
text: text,
 +
type: this._name,
 +
attributes: apoc.map.fromPairs([x in keys(this) WHERE not x starts with "_" | [x, this[x]] ])
 +
} as standoffProperty
 +
return {text: allText, properties: collect(standoffProperty)};
 +
</code>
 +
 +
 
This json can then be imported in the [[https://github.com/argimenes/standoff-properties-editor SPEEDy]] Standoff Property Editor which can be found on [[https://github.com/argimenes/standoff-properties-editor GitHub]].
 
This json can then be imported in the [[https://github.com/argimenes/standoff-properties-editor SPEEDy]] Standoff Property Editor which can be found on [[https://github.com/argimenes/standoff-properties-editor GitHub]].
  

Revision as of 11:39, 2 March 2022

Andreas Kuczera, Iian Neill, Stefan Armbruster

Introduction

As TEI is not a format, though many people think it is. It's a de facto standard that specifies Guidelines for document interchange. Actually the Guidelines are based on the XML but this is only one possible technical way of expressing the phenomenons.

The aim of the Graph-SIG is to find a way of expressing the language phenomenons of the TEI in Graphs.

  • In the graph you can use multi-hierarchical annotations layers.
  • Graph models are very easy to read and understand. So DH-People and “normal” scientists have a level of discussion in common.
  • A Graph can be expressed as RDF so the step from a Graph to linked open data is easy to make.

The main goal of the TEI-Graph-SIG is to model the textual phenomenons of the TEI in a Graph and to develop routines to import TEI-encoded XML-files into graph databases.

Convert DTA-XML with neo4j to Standoff Property JSON

In a first step we import a small xml-example into a neo4j instance using apoc.import.xml

The example is a page from the DTA. Here you can find the XML-Testfile and this is the Link to the DTA-Version.

Import into neo4j

The import into neo4j runs with:

// Import xml-example from DTA to neo4j
call apoc.import.xml('https://seafile.rlp.net/f/6282a26504cc4f079ab9/?dl=1', {connectCharacters: true, charactersForTag:{lb:' '}, filterLeadingWhitespace: true}) yield node 
return node;

In the next picture you can see a small set of the Graph:

x

Export from neo4j to Standoff Property JSON

The next step is to export the data with some cypher to the Standoff-Property JSON-Format.

// Export TEI-Graph to Standoff-Property-JSON-Format by Stefan Armbruster
match path=(d:XmlDocument)-[:NE*]->(e:XmlCharacters)
where not (e)-[:NE]->()
with tail(nodes(path)) as words, d
with reduce(s="", x in words| s + x.text ) as allText, d
call apoc.path.expandConfig(d,{
relationshipFilter: '<IS_CHILD_OF',
labelFilter: 'XmlTag',
bfs: false,
minLevel: 1
}) yield path
with allText, path, nodes(path)[-1] as this
MATCH p=(this)-[:NEXT*]->(x)
where (x)-[:LAST_CHILD_OF*]->(this) and any(x in nodes(p) WHERE x:XmlCharacters)
with allText, this, collect(p)[-1] as longest
with allText, this, [x in nodes(longest) where x:XmlCharacters] as xmlCharacters
with allText, this, 
apoc.coll.min([x in xmlCharacters | x.startIndex]) as min, 
apoc.coll.max([x in xmlCharacters | x.endIndex]) as max, 
apoc.text.join([x in xmlCharacters | x.text], "") as text
with allText, {
index:id(this), 
startIndex: min, 
endIndex: max,
text: text,
type: this._name,
attributes: apoc.map.fromPairs([x in keys(this) WHERE not x starts with "_" | [x, this[x]] ])
} as standoffProperty
return {text: allText, properties: collect(standoffProperty)};


This json can then be imported in the [SPEEDy] Standoff Property Editor which can be found on [GitHub].

At the end of the README-Section you can find a [Link] to Test-Istance hosted on [Github-Pages].

Just copy the JSON-Export in the window below the UNBIND-Button of SPEEDy and press BIND.

The next picture shows SPEEDy with the test.json. You can choose the example file in the top selection box of SPEEDy as well.

x

I want to say thanks to Stefan Armbruster from neo4j for the export-cypher-query and the implementation of the XML-Import functions to apoc and Iian Neill for his work on SPEEDy.