piprate/json-gold

Turtle (TTL) RDF to JSON-LD to an Object

BoraBak opened this issue · 3 comments

Hello,
my main goal is to convert .ttl file format to an object or a "simple" .json file format.
For that, I'm converting the .ttl file to a json-ld. And from there, using the current repo, convert from json-ld to an object.


I tried 2 options in order to convert a .ttl file format to json-ld file format.

  1. using github.com/deiu/rdf2go - worked
func convertTtlToJsonLd1() error {
	w, _ := os.OpenFile("data/hosts-ld.json", os.O_CREATE|os.O_WRONLY, 0644)
	r, _ := os.OpenFile("data/hosts.ttl", os.O_CREATE|os.O_RDONLY, 0664)
	g := rdf2go.NewGraph("baseUri")
	if err := g.Parse(r, "text/turtle"); err != nil {
		return err
	}
	return g.Serialize(w, "application/ld+json")
}
  1. using github.com/piprate/json-gold/ld - didn't work: throwing the following error panic: runtime error: invalid memory address or nil pointer dereference
func convertTtlToJsonLd2() {
	f, err := ioutil.ReadFile("data/hosts-test.ttl")
	if err != nil {
		panic(err)
	}

	triples := string(f)

	proc := ld.NewJsonLdProcessor()
	options := ld.NewJsonLdOptions("")

	doc, err := proc.FromRDF(triples, options)
	if err != nil {
		panic(err)
	}

	ld.PrintDocument("JSON-LD output", doc)
}

I verified the conversion from TTL to json-ld in the following website: http://rdfvalidator.mybluemix.net/


Then, I tried to convert the json-ld to an object:
The object I'm converting to is Host.
Assume that both outputs from the above functions are writing to data/hosts-ld.json file.

func testJsonLd() {
	f, err := ioutil.ReadFile("data/hosts-ld.json")
	if err != nil {
		panic(err)
	}

	jsnLd := string(f)
	var p Host
	if err := jsonld.Unmarshal([]byte(jsnLd), &p); err != nil {
		log.Fatal(err)
	}

	fmt.Println(p)
}

hosts-test.ttl

@prefix ns3:    <http://xmlns.com/foaf/0.1/> .
@prefix owl:    <http://www.w3.org/2002/07/owl#> .
@prefix ns0:    <http://example.org/prop#> .


ns0:Account_0abb0c18-9fb7-57f2-8bcd-2cb07ffbe865_161
    a              ns0:Account ;
    ns0:GroupName  "Administrators" ;
    ns0:ID         "0abb0c18-9fb7-57f2-8bcd-2cb07ffbe865_161" ;
    ns0:Privileges "SeRemoteInteractiveLogonRight" ;
    ns0:UserId     "161" ;
    ns0:Username   "administrator" .


ns0:Host_48d491d1-7998-59d6-b3ed-07a0868d7536_531
    a                                 ns0:Host ;
    ns0:Exploitable                   "XXE", "PEC";
    ns0:Account                       ns0:Account_0abb0c18-9fb7-57f2-8bcd-2cb07ffbe865_161 ;
    ns0:HostSignificance              "3" ;
    ns0:ID                            "48d491d1-7998-59d6-b3ed-07a0868d7536_531" .



ns0:Host
    a owl:Class .

ns0:Account
    a owl:ObjectProperty, owl:Class .

ns0:Exploitable
    a owl:DatatypeProperty .

ns0:GroupName
    a owl:DatatypeProperty .

ns0:HostSignificance
    a owl:DatatypeProperty .

ns0:ID
    a owl:DatatypeProperty .

ns0:IP
    a owl:DatatypeProperty .

ns0:LocalAccountTokenFilterPolicy
    a owl:DatatypeProperty .

ns0:LsaRunAsPPL
    a owl:DatatypeProperty .

ns0:Privileges
    a owl:DatatypeProperty .

ns0:UserId
    a owl:DatatypeProperty .

ns0:Username
    a owl:DatatypeProperty .

Below is the json-ld file from the function convertTtlToJsonLd1().
Note. the json-ld below is different from the outputs from the website: http://rdfvalidator.mybluemix.net/

[
  {
    "@id": "http://example.org/prop#HostSignificance",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": [
      {
        "@id": "http://www.w3.org/2002/07/owl#DatatypeProperty"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#IP",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": [
      {
        "@id": "http://www.w3.org/2002/07/owl#DatatypeProperty"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#UserId",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": [
      {
        "@id": "http://www.w3.org/2002/07/owl#DatatypeProperty"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#GroupName",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": [
      {
        "@id": "http://www.w3.org/2002/07/owl#DatatypeProperty"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#ID",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": [
      {
        "@id": "http://www.w3.org/2002/07/owl#DatatypeProperty"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#LsaRunAsPPL",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": [
      {
        "@id": "http://www.w3.org/2002/07/owl#DatatypeProperty"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#Username",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": [
      {
        "@id": "http://www.w3.org/2002/07/owl#DatatypeProperty"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#Host_48d491d1-7998-59d6-b3ed-07a0868d7536_531",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": [
      {
        "@id": "http://example.org/prop#Host"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#Host_48d491d1-7998-59d6-b3ed-07a0868d7536_531",
    "http://example.org/prop#Account": [
      {
        "@id": "http://example.org/prop#Account_0abb0c18-9fb7-57f2-8bcd-2cb07ffbe865_161"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#Account",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": [
      {
        "@id": "http://www.w3.org/2002/07/owl#Class"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#Host_48d491d1-7998-59d6-b3ed-07a0868d7536_531",
    "http://example.org/prop#Exploitable": [
      {
        "@value": "PEC"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#Host_48d491d1-7998-59d6-b3ed-07a0868d7536_531",
    "http://example.org/prop#HostSignificance": [
      {
        "@value": "3"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#Account",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": [
      {
        "@id": "http://www.w3.org/2002/07/owl#ObjectProperty"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#Exploitable",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": [
      {
        "@id": "http://www.w3.org/2002/07/owl#DatatypeProperty"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#Privileges",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": [
      {
        "@id": "http://www.w3.org/2002/07/owl#DatatypeProperty"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#Account_0abb0c18-9fb7-57f2-8bcd-2cb07ffbe865_161",
    "http://example.org/prop#UserId": [
      {
        "@value": "161"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#Account_0abb0c18-9fb7-57f2-8bcd-2cb07ffbe865_161",
    "http://example.org/prop#Username": [
      {
        "@value": "administrator"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#Host_48d491d1-7998-59d6-b3ed-07a0868d7536_531",
    "http://example.org/prop#Exploitable": [
      {
        "@value": "XXE"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#Account_0abb0c18-9fb7-57f2-8bcd-2cb07ffbe865_161",
    "http://example.org/prop#Privileges": [
      {
        "@value": "SeRemoteInteractiveLogonRight"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#Host_48d491d1-7998-59d6-b3ed-07a0868d7536_531",
    "http://example.org/prop#ID": [
      {
        "@value": "48d491d1-7998-59d6-b3ed-07a0868d7536_531"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#Host",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": [
      {
        "@id": "http://www.w3.org/2002/07/owl#Class"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#LocalAccountTokenFilterPolicy",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": [
      {
        "@id": "http://www.w3.org/2002/07/owl#DatatypeProperty"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#Account_0abb0c18-9fb7-57f2-8bcd-2cb07ffbe865_161",
    "http://www.w3.org/1999/02/22-rdf-syntax-ns#type": [
      {
        "@id": "http://example.org/prop#Account"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#Account_0abb0c18-9fb7-57f2-8bcd-2cb07ffbe865_161",
    "http://example.org/prop#GroupName": [
      {
        "@value": "Administrators"
      }
    ]
  },
  {
    "@id": "http://example.org/prop#Account_0abb0c18-9fb7-57f2-8bcd-2cb07ffbe865_161",
    "http://example.org/prop#ID": [
      {
        "@value": "0abb0c18-9fb7-57f2-8bcd-2cb07ffbe865_161"
      }
    ]
  }
]

The Host struct:

type Host struct {
	ID               string    `jsonld:"http://example.org/prop#ID"`
	Account          []Account `jsonld:"http://example.org/prop#Account"`
	HostSignificance string    `jsonld:"http://example.org/prop#HostSignificance"`
	Exploitable      []string  `jsonld:"http://example.org/prop#Exploitable"`
}

type Account struct {
	ID         string   `jsonld:"http://example.org/prop#ID"`
	UserId     string   `jsonld:"http://example.org/prop#UserId"`
	Username   string   `jsonld:"http://example.org/prop#Username"`
	GroupName  []string `jsonld:"http://example.org/prop#GroupName"`
	Privileges []string `jsonld:"http://example.org/prop#Privileges"`
}

Maybe if someone can supply a code example of: TTL -> JSON-LD -> Object

After investigation of the current, it seems that there is no support to parse Turtle from string into an RDFDataset:

return nil, NewJsonLdError(NotImplemented, "Turtle not supported")
🤦‍♂️

Nevertheless, if someone could write what's the logical path a program should go through in order to achieve a conversion from a TTL file to a Golang structs?

@BoraBak, apologies for neglecting your issue report. As you have identified, JSON-goLD doesn't support Turtle as either input or output format. At the time this library was created there was no readily available Turtle processing package in Go. Maybe it exists now. If you are aware of one, please let me know and I'll see if I can add support for Turtle. PRs are also welcome.