About this site
Linked Art is a community data model for describing art and cultural heritage, built on CIDOC-CRM and published as JSON-LD. LinkedArtNet is a .NET implementation of Linked Art 1.0: a typed model with a fluent API, a free-text date parser, a parsing service, and this site.
Why C#?
JSON-LD examples are precise but hard to read in bulk. The same example as fluent C# reads like a description of the thing: a painting, produced by someone, at some time, carrying a title. Every example here is checked against the JSON that linked.art publishes, so the code you read is known to produce the real thing. Where it does not, the page says so and links the upstream issue.
Using the library
Packages are not yet on NuGet; build from source. The repository README has the quick start. The libraries target .NET 10.
A painting, its maker and its measurements
var rembrandt = Ulan.Person("500011051", "Rembrandt van Rijn");
var painting = new HumanMadeObject()
.WithId("https://example.org/object/nightwatch")
.WithLabel("The Night Watch")
.WithClassifiedAs(Aat.Painting, Aat.TypeOfWork)
.WithName("The Night Watch", n => n.AsPrimaryName().WithLanguage(Aat.English))
.WithName("De Nachtwacht", n => n.WithLanguage(Aat.Dutch))
.WithIdentifier("SK-C-5", i => i.AsAccessionNumber())
.WithProducedBy(p => p
.WithCarriedOutBy(rembrandt)
.WithTookPlaceAt(Tgn.Place("7006952", "Amsterdam"))
.WithTimeSpan("1642"))
.WithHeightDimension(379.5, Aat.Centimeters)
.WithWidthDimension(453.5, Aat.Centimeters)
.WithStatement(Aat.MaterialsStatement, "oil on canvas");
{
"id": "https://example.org/object/nightwatch",
"type": "HumanMadeObject",
"_label": "The Night Watch",
"produced_by": {
"type": "Production",
"carried_out_by": [
{
"id": "http://vocab.getty.edu/ulan/500011051",
"type": "Person",
"_label": "Rembrandt van Rijn"
}
],
"timespan": {
"type": "TimeSpan",
"_label": "1642",
"begin_of_the_begin": "1642-01-01T00:00:00Z",
"end_of_the_end": "1642-12-31T23:59:59Z"
},
"took_place_at": [
{
"id": "http://vocab.getty.edu/tgn/7006952",
"type": "Place",
"_label": "Amsterdam"
}
]
},
"dimension": [
{
"type": "Dimension",
"value": 379.5,
"unit": {
"id": "http://vocab.getty.edu/aat/300379098",
"type": "MeasurementUnit",
"_label": "centimeters"
},
"classified_as": [
{
"id": "http://vocab.getty.edu/aat/300055644",
"type": "Type",
"_label": "Height"
}
]
},
{
"type": "Dimension",
"value": 453.5,
"unit": {
"id": "http://vocab.getty.edu/aat/300379098",
"type": "MeasurementUnit",
"_label": "centimeters"
},
"classified_as": [
{
"id": "http://vocab.getty.edu/aat/300055647",
"type": "Type",
"_label": "Width"
}
]
}
],
"classified_as": [
{
"id": "http://vocab.getty.edu/aat/300033618",
"type": "Type",
"_label": "Painting",
"classified_as": [
{
"id": "http://vocab.getty.edu/aat/300435443",
"type": "Type",
"_label": "Type of Work"
}
]
}
],
"identified_by": [
{
"type": "Name",
"content": "The Night Watch",
"language": [
{
"id": "http://vocab.getty.edu/aat/300388277",
"type": "Language",
"_label": "English",
"notation": "en"
}
],
"classified_as": [
{
"id": "http://vocab.getty.edu/aat/300404670",
"type": "Type",
"_label": "Primary Name"
}
]
},
{
"type": "Name",
"content": "De Nachtwacht",
"language": [
{
"id": "http://vocab.getty.edu/aat/300388256",
"type": "Language",
"_label": "Dutch",
"notation": "nl"
}
]
},
{
"type": "Identifier",
"content": "SK-C-5",
"classified_as": [
{
"id": "http://vocab.getty.edu/aat/300312355",
"type": "Type",
"_label": "Accession Number"
}
]
}
],
"referred_to_by": [
{
"type": "LinguisticObject",
"content": "oil on canvas",
"classified_as": [
{
"id": "http://vocab.getty.edu/aat/300435429",
"type": "Type",
"_label": "Material Statement",
"classified_as": [
{
"id": "http://vocab.getty.edu/aat/300418049",
"type": "Type",
"_label": "Brief Text"
}
]
}
]
}
]
}
Produced by running the C# shown, at the time the page was served; the code is read from the same source file it compiles from.
Canonical date expressions
The date parser reduces every input to a small canonical language before producing a TimeSpan: EDTF where EDTF can say it
(1957/1959, 1850~), and a few keywords where it cannot (late 195X, century 19,
born 1606, fl 1480/1510, period:edo, 4.5 Ga ago). The same canonical form
always realises to the same TimeSpan under a given profile, which is what makes the corpus testable. The language is documented in
docs/canonical-expression.md.
EDTF
The Extended Date/Time Format is the Library of Congress profile of
ISO 8601-2019 for dates as they occur in cultural heritage records: intervals (1606/1669), approximate and
uncertain dates (1850~, 1850?), unspecified digits (195X), seasons (1969-21
is spring 1969) and open ends (../1936). Many catalogues and the Linked Art community already exchange dates in it.
The playground shows the EDTF form of a reading whenever one exists; period names, floruit dates, lifecycle pairs and
the vaguer bands have no EDTF equivalent, so that row is absent for them and the canonical expression carries the meaning.
Profiles
Conventions differ: "19th century" is 1800 to 1899 in a museum label, and 1801
to 1900 to anyone counting strictly from year 1, since there was no year zero. "Early" is a third to
some and a half to others; US archives write month first. A profile fixes these choices. The repository ships
default, library, archive-us, catalogue-quarters, medieval-manuscripts
and multilingual, and a profile advisor that proposes settings from a sample of your strings.
The corpus and its sources
Every entry in the corpus states where it came from. Imported collections, each under a licence compatible with this project's MIT licence:
- yearrange (MIT), the test data of John Resig's year-range parser: museum catalogue dates, largely from Japanese print collections. In the corpus browser.
- timetwister (MIT), the specification examples of Alex Duryee's date normalisation gem, written at the New York Public Library: archival date forms. In the corpus browser.
- Getty ULAN (ODC-By), biography descriptions from the Union List of Artist Names, fetched from the Getty SPARQL endpoint. In the corpus browser.
- PeriodO (CC0), the gazetteer of period definitions from published sources,
compacted into
periods/periodo.jsonso that period names ("Iron Age", "Early Bronze II") resolve to dated spans and, where one source defines the name, to PeriodO's permanent URI. The definitions belong to the authorities PeriodO cites, and the parser's notes name them. Not corpus data: a reference table the parser reads. - EDTF specification (public domain), the Library of Congress's examples, level by level. In the corpus browser.
Two further collections were seeded from this project's own history and carry the repository's licence: the date strings
found in the Paul Mellon Centre pipeline's outputs, and the test strings of Digirati's earlier py_datetime prototype
for University of the Arts, London (UAL).
Named period tables (Japanese eras, Chinese dynasties, British periods, archaeological ages) and the seven language lexicons
state their provenance inside each file. Full notices are in
THIRD-PARTY-NOTICES.md,
and the corpus itself, with its README
and the guide to contributing,
is in the repository under corpus/.
Licence
LinkedArtNet is MIT licensed. The examples' content is linked.art's, reproduced here for comparison; linked.art is published under CC BY 4.0 by the Linked Art community. Getty vocabulary terms are referenced by URI under the Getty's ODC-By licence.