Home » XML » XML_XRD » Manual
XML_XRD is a PHP library to parse and generate Extensible Resource Descriptor (XRD) Version 1.0 and JRD (JSON-based) files. XRD files are used for .well-known/host-meta files as standardized in RFC 6415: Web Host Metadata as well as in the LRDD (Link-based Resource Descriptor Discovery) files linked from it. JRD files are used by WebFinger, which lets people use their e-mail address to do OpenID sign in. The XRD format supercedes the XRDS format defined in XRI 2.0, which is used in the Yadis communications protocol.
How to use the package
At first, you need to include the main XML_XRD
file and create a new
XML_XRD object:
<?php
require_once 'XML/XRD.php';
$xrd = new XML_XRD();
?>
When that's done, you load the XRD file or string, then verify if the resource is really the resource you wanted to load and then access the links and the properties of the XRD object.
Also read the sections about error handling and XRD creation.
Fetching LRDD URI from host-meta
<?php
require_once 'XML/XRD.php';
$xrd = new XML_XRD();
try {
$xrd->loadFile('http://cweiske.de/.well-known/host-meta');
} catch (XML_XRD_Exception $e) {
die('Loading XRD file failed: ' . $e->getMessage());
}
$link = $xrd->get('lrdd', 'application/xrd+xml');
if ($link === null) {
die('No LRDD link found');
}
$template = $link->template;
$lrddUri = str_replace('{uri}', urlencode('acct:cweiske@cweiske.de'), $template);
echo 'URL with infos about cweiske@cweiske.de is ' . $lrddUri . "\n";
?>
Loading an XRD file
XRD .xml files may be loaded directly from a
file,
or from a
string:
Loading an XRD file
<?php
try {
$xrd->loadFile('/path/to/the/file.xrd', 'xml');
} catch (XML_XRD_Exception $e) {
die('Loading XRD file failed: ' . $e->getMessage() . "\n");
}
?>
Loading an XRD string
<?php
try {
$xrd->loadString($fullXrdXmlHere, 'xml');
} catch (XML_XRD_Exception $e) {
die('Loading XRD failed: ' . $e->getMessage() . "\n");
}
?>
XML_XRD tries to autodetect if the file is XML or JSON (JRD)
and use the correct loader.
You can make its life easier (and skip autodetection, and reduce network load)
by passing the type parameter:
Loading a JRD file
<?php
try {
$xrd->loadFile('/path/to/the/file.jrd', 'json');
} catch (XML_XRD_Exception $e) {
die('Loading JRD file failed: ' . $e->getMessage() . "\n");
}
?>
Verification
After loading a XRD file, you should make sure that it really describes
the resource/URL you are looking for.
describes()
checks both the subject and alias tags:
<?php
require_once 'XML/XRD.php';
$xrd = new XML_XRD();
$xrd->loadFile('http://example.org/.well-known/host-meta');
if (!$xrd->describes('http://example.org/')) {
die('XRD document is not the correct one for http://example.org/');
}
?>
Accessing links
The XML_XRD object offers three ways to access links:
-
Use
foreachto iterate over the object and get all links - get() to fetch a single link with certain properties
- getAll() to fetch all links that have certain properties
The returned links are objects of type XML_XRD_Element_Link which has several properties, e.g. rel, href, type and template .
Fetching links
Get all links
<?php
require_once 'XML/XRD.php';
$xrd = new XML_XRD();
$xrd->loadFile('http://example.org/.well-known/host-meta');
foreach ($xrd as $link) {
echo $link->rel . ': ' . $link->href . "\n";
}
?>
Get link by relation
<?php
require_once 'XML/XRD.php';
$xrd = new XML_XRD();
$xrd->loadFile('http://example.org/.well-known/host-meta');
$idpLink = $xrd->get('lrdd');
echo $idpLink->rel . ': ' . $idpLink->href . "\n";
?>
Get link by relation + optional type
If no link with the given type
is found, the first link with the correct
relation and an empty
type will be returned
<?php
require_once 'XML/XRD.php';
$xrd = new XML_XRD();
$xrd->loadFile('http://example.org/.well-known/host-meta');
$link = $xrd->get('lrdd', 'application/xrd+xml');
echo $link->rel . ': ' . $link->href . "\n";
?>
Get link by relation + type
The relation and the type
both need to match exact:
<?php
require_once 'XML/XRD.php';
$xrd = new XML_XRD();
$xrd->loadFile('http://example.org/.well-known/host-meta');
$link = $xrd->get('lrdd', 'application/xrd+xml', false);
echo $link->rel . ': ' . $link->href . "\n";
?>
Get all links by relation
<?php
require_once 'XML/XRD.php';
$xrd = new XML_XRD();
$xrd->loadFile('http://example.org/.well-known/host-meta');
foreach ($xrd->getAll('lrdd') as $link) {
echo $link->rel . ': ' . $link->href . "\n";
}
?>
Working with links
Accessing all link attributes
<?php
$link = $xrd->get('http://specs.openid.net/auth/2.0/provider');
$title = $link->getTitle('de');
$url = $link->href;
$urlTemplate = $link->template;
$mimetype = $link->type;
?>
Additional link properties
Works just like properties in the XRD document.
<?php
$link = $xrd->get('http://specs.openid.net/auth/2.0/provider');
$prop = $link['foo'];
?>
Accessing properties
Properties of XRD files and link elements can be accessed by using its ArrayAccess interface or the getProperties() method. The returned properties are objects of type XML_XRD_Element_Property.
Get a single property
<?php
require_once 'XML/XRD.php';
$xrd = new XML_XRD();
$xrd->loadFile('http://example.org/.well-known/host-meta');
if (isset($xrd['http://spec.example.net/type/person'])) {
echo $xrd['http://spec.example.net/type/person'] . "\n";
}
?>
Get all properties
<?php
require_once 'XML/XRD.php';
$xrd = new XML_XRD();
$xrd->loadFile('http://example.org/.well-known/host-meta');
foreach ($xrd->getProperties() as $property) {
echo $property->type . ': ' . $property->value . "\n";
}
?>
Get all properties of a type
<?php
require_once 'XML/XRD.php';
$xrd = new XML_XRD();
$xrd->loadFile('http://example.org/.well-known/host-meta');
foreach ($xrd->getProperties('http://spec.example.net/type/person') as $property) {
echo $property->type . ': ' . $property->value . "\n";
}
?>
Error handling
When loading a file, exceptions of type
XML_XRD_Exception
may be thrown.
All other parts of the code do not throw exceptions but fail gracefully by returning
null, e.g. when a property does not exist.
Using loadFile() may result in PHP warnings like:
Warning: simplexml_load_file(https://example.org/) failed to open stream: Connection refused
This cannot be prevented properly, so you either have to silence it with
@ or fetch the file manually and use
loadString().
Generating XRD files
Generating XRD files is made by creating an XML_XRD object, setting
the properties and calling the generation method
to()
with either xml or json as only
parameter.
<?php
require_once 'XML/XRD.php';
$x = new XML_XRD();
$x->subject = 'example.org';
$x->aliases[] = 'example.com';
$x->links[] = new XML_XRD_Element_Link(
'lrdd', 'http://example.org/gen-lrdd.php?a={uri}',
'application/xrd+xml', true
);
echo $x->to('xml');
?>
Generate a LRDD file
<?php
require_once 'XML/XRD.php';
$x = new XML_XRD();
$x->subject = 'user@example.org';
//add link to the user's OpenID
$x->links[] = new XML_XRD_Element_Link(
'http://specs.openid.net/auth/2.0/provider',
'http://id.example.org/user'
);
//add link to user's home page
$x->links[] = new XML_XRD_Element_Link(
'http://xmlns.com/foaf/0.1/homepage',
'http://example.org/~user/'
);
echo $x->to('xml');
?>