Technical Artifacts

JSON-LD Contexts

Semantic web integration with JSON-LD contexts

JSON-LD (JSON for Linking Data) extends regular JSON with semantic meaning by mapping field names to globally unique URIs. ZineCore2 provides JSON-LD contexts for each profile, enabling integration with RDF systems, SPARQL queries, and the broader semantic web.

What is JSON-LD?

JSON-LD adds a @context to regular JSON, transforming simple data into linked data:

{
  "@context": "https://zinecore.org/v2/context/zinecore2",
  "title": "Riot Grrrl",
  "creator": ["Kathleen Hanna"],
  "subject": ["feminism"]
}

This maps title → dcterms:title, creator → dcterms:creator, and so on, giving each field a globally unique identifier.

Available Contexts

Quick Testing

Use the JSON-LD Playground to expand, compact, and frame JSON-LD documents without installing anything.

Content Negotiation

ZineCore2 context URIs support content negotiation:

# Request HTML documentation (default)
curl https://zinecore.org/v2/context/zinecore2

# Request JSON-LD context
curl -H "Accept: application/ld+json" \
  https://zinecore.org/v2/context/zinecore2

This allows the same URI to serve both human-readable docs and machine-readable contexts.

Using JSON-LD Contexts

Expanding JSON-LD

Expansion converts compact field names to full URIs:

Input (compact):

{
  "@context": "https://zinecore.org/v2/context/zinecore2",
  "title": "Riot Grrrl",
  "creator": ["Kathleen Hanna"],
  "date": "1991"
}

Output (expanded):

[
  {
    "http://purl.org/dc/terms/title": [
      { "@value": "Riot Grrrl" }
    ],
    "http://purl.org/dc/terms/creator": [
      { "@value": "Kathleen Hanna" }
    ],
    "http://purl.org/dc/terms/date": [
      { "@value": "1991" }
    ]
  }
]

With jsonld.js (JavaScript)

npm install jsonld
import jsonld from 'jsonld';

const doc = {
  "@context": "https://zinecore.org/v2/context/zinecore2",
  "title": "Riot Grrrl",
  "creator": ["Kathleen Hanna"],
  "date": "1991",
  "subject": ["feminism", "punk-culture"]
};

// Expand to full URIs
const expanded = await jsonld.expand(doc);
console.log(JSON.stringify(expanded, null, 2));

// Compact with a different context
const compacted = await jsonld.compact(expanded, {
  "@context": "https://zinecore.org/v2/context/zinecore2"
});

// Convert to N-Quads (RDF)
const nquads = await jsonld.toRDF(doc, { format: 'application/n-quads' });
console.log(nquads);

With PyLD (Python)

pip install PyLD
from pyld import jsonld
import json

doc = {
    "@context": "https://zinecore.org/v2/context/zinecore2",
    "title": "Riot Grrrl",
    "creator": ["Kathleen Hanna"],
    "date": "1991",
    "subject": ["feminism", "punk-culture"]
}

# Expand
expanded = jsonld.expand(doc)
print(json.dumps(expanded, indent=2))

# Convert to RDF (N-Quads)
nquads = jsonld.to_rdf(doc, {'format': 'application/n-quads'})
print(nquads)

# Compact with context
compacted = jsonld.compact(expanded, "https://zinecore.org/v2/context/zinecore2")
print(json.dumps(compacted, indent=2))

Integration with RDF Systems

Loading into a Triple Store

Convert JSON-LD to N-Triples and load into Apache Jena, Blazegraph, or other RDF databases:

from pyld import jsonld
from rdflib import Graph

# Convert JSON-LD to RDF
doc = {
    "@context": "https://zinecore.org/v2/context/zinecore2",
    "title": "Riot Grrrl",
    "creator": ["Kathleen Hanna"]
}

nquads = jsonld.to_rdf(doc, {'format': 'application/n-quads'})

# Load into RDFLib graph
g = Graph()
g.parse(data=nquads, format='nquads')

# Query with SPARQL
query = """
PREFIX dcterms: <http://purl.org/dc/terms/>
SELECT ?title ?creator
WHERE {
    ?zine dcterms:title ?title .
    ?zine dcterms:creator ?creator .
}
"""

for row in g.query(query):
    print(f"Title: {row.title}, Creator: {row.creator}")

SPARQL Queries

Once loaded into a triple store, query across multiple records:

PREFIX dcterms: <http://purl.org/dc/terms/>
PREFIX zine: <https://zinecore.org/v2/zine#>

# Find all zines about feminism published in the 1990s
SELECT ?title ?creator ?date
WHERE {
    ?z dcterms:title ?title ;
       dcterms:creator ?creator ;
       dcterms:date ?date ;
       dcterms:subject ?subject .

    FILTER(CONTAINS(STR(?subject), "feminism"))
    FILTER(REGEX(?date, "^199"))
}
ORDER BY ?date

Dublin Core Alignment

ZineCore2 contexts map primarily to Dublin Core Terms (dcterms) with custom extensions under the zine: namespace:

Core Dublin Core Mappings

ZineCore2 FieldMaps To
titledcterms:title
creatordcterms:creator
contributordcterms:contributor
publisherdcterms:publisher
datedcterms:date
subjectdcterms:subject
abstractdcterms:description
languagedcterms:language
formatdcterms:format
rightsdcterms:rights
identifierdcterms:identifier
sourcedcterms:source
relationdcterms:relation

ZineCore2 Extensions

ZineCore2 FieldMaps ToNotes
genrezine:genreNo standard DC equivalent
issue_designationzine:issueDesignationZine-specific
binding_featureszine:bindingPhysical characteristics
public_noteszine:publicNotesCuratorial notes

See the ZineCore2 profile page for complete field mappings.

Framing JSON-LD

Framing reshapes JSON-LD into a specific structure, useful for generating nested representations:

const frame = {
  "@context": "https://zinecore.org/v2/context/zinecore2",
  "@type": "Zine",
  "title": {},
  "creator": {}
};

const framed = await jsonld.frame(doc, frame);

This is particularly useful when combining data from multiple sources or creating specific views of your data.

Cross-Profile Linking

When linking between profiles, use full URIs or ensure both contexts are loaded:

{
  "@context": [
    "https://zinecore.org/v2/context/zinecore2",
    "https://zinecore.org/v2/context/agentcore2"
  ],
  "@id": "https://example.org/zines/riot-grrrl",
  "@type": "Zine",
  "title": "Riot Grrrl",
  "creator": {
    "@id": "https://example.org/agents/kathleen-hanna",
    "@type": "Agent",
    "display_name": "Kathleen Hanna",
    "agent_kind": "Person"
  }
}

This creates a nested representation where the creator is fully resolved.

Linked Data Best Practices

Use Persistent URIs

When creating @id values for your records, use persistent, dereferenceable URIs:

{
  "@context": "https://zinecore.org/v2/context/zinecore2",
  "@id": "https://archive.example.org/zines/12345",
  "title": "Riot Grrrl"
}

Use identifier with @type for typed identifiers:

{
  "identifier": [
    {
      "@type": "ISBN",
      "@value": "978-0-123456-78-9"
    },
    {
      "@type": "OCLC",
      "@value": "ocm12345678"
    }
  ]
}

When using ZineCore2 vocabularies, you can reference the full vocabulary URIs:

{
  "subject": [
    { "@id": "https://zinecore.org/v2/vocab/subjects/feminism" },
    { "@id": "https://zinecore.org/v2/vocab/subjects/punk-culture" }
  ]
}

Or use the compact form (more common):

{
  "subject": ["feminism", "punk-culture"]
}

Both are valid; the context maps codes to full URIs automatically.

Validation and JSON-LD

JSON-LD validation is separate from JSON Schema validation:

  • JSON Schema validates structure and data types
  • SHACL (Shapes Constraint Language) validates RDF graph structures

For most use cases, JSON Schema validation is sufficient. Use SHACL if you need to validate graph patterns or relationships in an RDF triple store.

Tools and Libraries

JavaScript/TypeScript

Python

Ruby

Java

Command Line

Use Cases

Library Catalogs

Integrate ZineCore2 records with BIBFRAME or Schema.org:

{
  "@context": [
    "https://zinecore.org/v2/context/zinecore2",
    "http://schema.org/"
  ],
  "@type": ["Zine", "CreativeWork"],
  "title": "Riot Grrrl",
  "creator": ["Kathleen Hanna"]
}

Linked Open Data

Publish ZineCore2 records as part of a linked data cloud, connecting to Wikidata, VIAF, and other authority files:

{
  "@context": "https://zinecore.org/v2/context/agentcore2",
  "display_name": "Kathleen Hanna",
  "wikidata": "http://www.wikidata.org/entity/Q467251",
  "orcid": "https://orcid.org/0000-0000-0000-0000"
}

Use JSON-LD to enable semantic search capabilities:

  • Query across multiple metadata schemas
  • Discover related resources via linked data
  • Integrate with knowledge graphs

Next Steps

Copyright ©2026 ZineCore2 Contributors,