Skip to content

Commit 7656e94

Browse files
committed
Split $anchor from $id, update examples
This adds the $anchor keyword in place of the fragment-only form of $id, and updates the schema identification examples for $anchor and canonical vs non-canonical URIs.
1 parent a93b605 commit 7656e94

File tree

1 file changed

+136
-66
lines changed

1 file changed

+136
-66
lines changed

jsonschema-core.xml

Lines changed: 136 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1461,7 +1461,7 @@
14611461
</section>
14621462
</section>
14631463

1464-
<section title="Base URI and Dereferencing">
1464+
<section title="Base URI, Anchors, and Dereferencing">
14651465
<t>
14661466
To differentiate between schemas in a vast ecosystem, schemas are
14671467
identified by <xref target="RFC3986">URI</xref>, and can embed references
@@ -1586,24 +1586,60 @@
15861586
<xref target="idExamples" format="counter"></xref>.
15871587
</t>
15881588
</section>
1589-
<section title="Schema identification examples" anchor="idExamples">
1590-
<figure>
1591-
<preamble>
1592-
Consider the following schema, which shows "$id" being used to identify
1593-
the root schema, change the base URI for subschemas, and assign plain
1594-
name fragments to subschemas:
1595-
</preamble>
1596-
<artwork>
1589+
</section>
1590+
<section title='Defining location-independent identifiers with "$anchor"'
1591+
anchor="anchor">
1592+
<t>
1593+
Using JSON Pointer fragments requires knowledge of the structure of the schema.
1594+
When writing schema documents with the intention to provide re-usable
1595+
schemas, it may be preferable to use a plain name fragment that is not tied to
1596+
any particular structural location. This allows a subschema to be relocated
1597+
without requiring JSON Pointer references to be updated.
1598+
</t>
1599+
<t>
1600+
The "$anchor" keyword is used to specify such a fragment.
1601+
</t>
1602+
<t>
1603+
If present, the value of this keyword MUST be a string, which MUST start with
1604+
a letter ([A-Za-z]), followed by any number of letters, digits ([0-9]),
1605+
hyphens ("-"), underscores ("_"), colons (":"), or periods (".").
1606+
<cref>
1607+
Note that the anchor string does not include the "#" character,
1608+
as it is not a URI-reference. An "$anchor": "foo" becomes the
1609+
fragment "#foo" when used in a URI. See below for full examples.
1610+
</cref>
1611+
</t>
1612+
<t>
1613+
The base URI to which the resulting fragment is appended is determined
1614+
by the "$id" keyword as explained in the previous section.
1615+
Two "$anchor" keywords in the same schema document MAY have the same
1616+
value if they apply to different base URIs, as the resulting full URIs
1617+
will be distinct. However, the effect of two "$anchor" keywords with the
1618+
same value and the same base URI is undefined. Implementations MAY
1619+
raise an error if such usage is detected.
1620+
</t>
1621+
</section>
1622+
<section title="Schema identification examples" anchor="idExamples">
1623+
<figure>
1624+
<preamble>
1625+
Consider the following schema, which shows "$id" being used to identify
1626+
both the root schema and various subschemas, and "$anchor" being used
1627+
to define plain name fragment identifiers.
1628+
</preamble>
1629+
<artwork>
15971630
<![CDATA[
15981631
{
15991632
"$id": "https://example.com/root.json",
16001633
"$defs": {
1601-
"A": { "$id": "#foo" },
1634+
"A": { "$anchor": "foo" },
16021635
"B": {
16031636
"$id": "other.json",
16041637
"$defs": {
1605-
"X": { "$id": "#bar" },
1606-
"Y": { "$id": "t/inner.json" }
1638+
"X": { "$anchor": "bar" },
1639+
"Y": {
1640+
"$id": "t/inner.json",
1641+
"$anchor": "bar"
1642+
}
16071643
}
16081644
},
16091645
"C": {
@@ -1612,60 +1648,94 @@
16121648
}
16131649
}
16141650
]]>
1615-
</artwork>
1616-
</figure>
1617-
<t>
1618-
The schemas at the following URI-encoded <xref target="RFC6901">JSON
1619-
Pointers</xref> (relative to the root schema) have the following
1620-
base URIs, and are identifiable by any listed URI in accordance with
1621-
Section <xref target="fragments" format="counter"></xref> above:
1622-
</t>
1623-
<t>
1624-
<list style="hanging">
1625-
<t hangText="# (document root)">
1626-
<list>
1627-
<t>https://example.com/root.json</t>
1628-
<t>https://example.com/root.json#</t>
1629-
</list>
1630-
</t>
1631-
<t hangText="#/$defs/A">
1632-
<list>
1633-
<t>https://example.com/root.json#foo</t>
1634-
<t>https://example.com/root.json#/$defs/A</t>
1635-
</list>
1636-
</t>
1637-
<t hangText="#/$defs/B">
1638-
<list>
1639-
<t>https://example.com/other.json</t>
1640-
<t>https://example.com/other.json#</t>
1641-
<t>https://example.com/root.json#/$defs/B</t>
1642-
</list>
1643-
</t>
1644-
<t hangText="#/$defs/B/$defs/X">
1645-
<list>
1646-
<t>https://example.com/other.json#bar</t>
1647-
<t>https://example.com/other.json#/$defs/X</t>
1648-
<t>https://example.com/root.json#/$defs/B/$defs/X</t>
1649-
</list>
1650-
</t>
1651-
<t hangText="#/$defs/B/$defs/Y">
1652-
<list>
1653-
<t>https://example.com/t/inner.json</t>
1654-
<t>https://example.com/t/inner.json#</t>
1655-
<t>https://example.com/other.json#/$defs/Y</t>
1656-
<t>https://example.com/root.json#/$defs/B/$defs/Y</t>
1657-
</list>
1658-
</t>
1659-
<t hangText="#/$defs/C">
1660-
<list>
1661-
<t>urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f</t>
1662-
<t>urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f#</t>
1663-
<t>https://example.com/root.json#/$defs/C</t>
1664-
</list>
1665-
</t>
1666-
</list>
1667-
</t>
1668-
</section>
1651+
</artwork>
1652+
</figure>
1653+
<t>
1654+
The schemas at the following URI-encoded <xref target="RFC6901">JSON
1655+
Pointers</xref> (relative to the root schema) have the following
1656+
base URIs, and are identifiable by any listed URI in accordance with
1657+
Section <xref target="fragments" format="counter"></xref> above:
1658+
</t>
1659+
<t>
1660+
<list style="hanging">
1661+
<t hangText="# (document root)">
1662+
<list style="hanging">
1663+
<t hangText="canonical absolute-URI (and also base URI)">
1664+
https://example.com/root.json
1665+
</t>
1666+
<t hangText="canonical URI with pointer fragment">
1667+
https://example.com/root.json#
1668+
</t>
1669+
</list>
1670+
</t>
1671+
<t hangText="#/$defs/A">
1672+
<list>
1673+
<t hangText="base URI">https://example.com/root.json</t>
1674+
<t hangText="canonical URI with plain fragment">
1675+
https://example.com/root.json#foo
1676+
</t>
1677+
<t hangText="canonical URI with pointer fragment">
1678+
https://example.com/root.json#/$defs/A
1679+
</t>
1680+
</list>
1681+
</t>
1682+
<t hangText="#/$defs/B">
1683+
<list style="hanging">
1684+
<t hangText="base URI">https://example.com/other.json</t>
1685+
<t hangText="canonical URI with pointer fragment">
1686+
https://example.com/other.json#
1687+
</t>
1688+
<t hangText="Fragment relative to root.json (undefined behavior)">
1689+
https://example.com/root.json#/$defs/B
1690+
</t>
1691+
</list>
1692+
</t>
1693+
<t hangText="#/$defs/B/$defs/X">
1694+
<list style="hanging">
1695+
<t hangText="base URI">https://example.com/other.json</t>
1696+
<t hangText="canonical URI with plain fragment">
1697+
https://example.com/other.json#bar
1698+
</t>
1699+
<t hangText="canonical URI with pointer fragment">
1700+
https://example.com/other.json#/$defs/X
1701+
</t>
1702+
<t hangText="Fragment relative to root.json (undefined behavior)">
1703+
https://example.com/root.json#/$defs/B/$defs/X
1704+
</t>
1705+
</list>
1706+
</t>
1707+
<t hangText="#/$defs/B/$defs/Y">
1708+
<list style="hanging">
1709+
<t hangText="base URI">https://example.com/t/inner.json</t>
1710+
<t hangText="canonical URI with plain fragment">
1711+
https://example.com/t/inner.json#bar
1712+
</t>
1713+
<t hangText="canonical URI with pointer fragment">
1714+
https://example.com/t/inner.json#
1715+
</t>
1716+
<t hangText="Fragment relative to other.json (undefined behavior)">
1717+
https://example.com/other.json#/$defs/Y
1718+
</t>
1719+
<t hangText="Fragment relative to root.json (undefined behavior)">
1720+
https://example.com/root.json#/$defs/B/$defs/Y
1721+
</t>
1722+
</list>
1723+
</t>
1724+
<t hangText="#/$defs/C">
1725+
<list style="hanging">
1726+
<t hangText="base URI">
1727+
urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f
1728+
</t>
1729+
<t hangText="canonical URI with pointer fragment">
1730+
urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f#
1731+
</t>
1732+
<t hangText="Fragment relative to root.json (undefined behavior)">
1733+
https://example.com/root.json#/$defs/C
1734+
</t>
1735+
</list>
1736+
</t>
1737+
</list>
1738+
</t>
16691739
</section>
16701740

16711741
<section title="Schema References" anchor="references">

0 commit comments

Comments
 (0)