---
title: "Validating cross-references"
source: https://dev.pageseeder.com/reference/sample_code/schematron/validating_cross-references.html
last_updated: 2026-09-05T17:36:31+10:00
tokens: ~736
---

# Validating cross-references

PageSeeder supports the expression of linked collections using [xrefs](../../glossary/cross_reference.md), including cases where part of the collection is outside PageSeeder.

## Basics

### Cross-reference rule

Rules applying to cross-references match the `<xref>` element, `<blockxref>` element or both:

```xml

<!-- Matches both inline and block cross-references -->
<sch:rule match="xref|blockxref">

  <!-- Assertions and reports here ... -->

</sch:rule>
```

Cross-references that belong to an `<xref-fragment>` tend to have specific requirements. In that case, the following rule is more appropriate:

```xml

<!-- Matches both inline and block cross-references -->
<sch:rule match="xref-fragment/blockxref">

  <!-- Assertions and reports here ... -->

</sch:rule>
```

### Message

The message returned by Schematron when an assertion fails when reporting a condition is met allows the user to quickly identify the problem so that it can be fixed.

On the `<xref>` or `<blockxref>` element, users can see the type of cross-reference, level and the content of the reference, so the `@type` and `@level` attributes and `text()` are useful to help identify the cross-reference. The `@href` attribute can also be useful in cases where users are familiar with the file structures or name.

In the context of an xref fragment, the position of the cross-reference can also be useful using `position()` or `count(preceding-sibling::blockxref)+1`. The latter is more reliable in contexts where the position might be affected by the XPath used in the rule.

To know where to fix the problem, it is often useful to provide either the fragment or section ID.

#### Examples

Cross-references in default fragment:

```text
Cross-reference '<sch:value-of select="text()"/>' 
 of type '<sch:value-of select="@type"/>'
 in fragment <sch:value-of select="ancestor::fragment/@id"/> ...
```

Can be used to display:

*Cross-reference 'Program schedule' of type 'embed' in fragment 15 ...*

Cross-references in xref-fragments:

```text
Cross-reference '<sch:value-of select="text()"/>' 
 at position #<sch:value-of select="position()"/>
 in fragment <sch:value-of select="ancestor::fragment/@id"/> ...
```

Can be used to display:

*Cross-reference 'Program schedule' at position #17 in fragment 5 ...*

## Validating the reference

The most frequent constraint on a cross-reference is to ensure its integrity, that is, ensure that it is neither archived nor unresolved.

### Checking that a cross-reference is resolved

A cross-reference which cannot be resolved includes the `@unresolved` attribute.

The following assertion checks that a cross-reference is resolved:

```xml

<sch:rule context="xref|blockxref">

  <!-- Cross-reference has no 'unresolved' attribute -->
  <sch:assert test="not(@unresolved)">The cross-reference 
    '<sch:value-of select="text()"/>' is unresolved.
  </sch:assert>

</sch:rule>
```

