You are here

RdfXml.php in Zircon Profile 8

File

vendor/easyrdf/easyrdf/lib/EasyRdf/Serialiser/RdfXml.php
View source
<?php

/**
 * EasyRdf
 *
 * LICENSE
 *
 * Copyright (c) 2009-2013 Nicholas J Humfrey.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. The name of the author 'Nicholas J Humfrey" may be used to endorse or
 *    promote products derived from this software without specific prior
 *    written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * @package    EasyRdf
 * @copyright  Copyright (c) 2009-2013 Nicholas J Humfrey
 * @license    http://www.opensource.org/licenses/bsd-license.php
 */

/**
 * Class to serialise an EasyRdf_Graph to RDF/XML
 * with no external dependancies.
 *
 * @package    EasyRdf
 * @copyright  Copyright (c) 2009-2013 Nicholas J Humfrey
 * @license    http://www.opensource.org/licenses/bsd-license.php
 */
class EasyRdf_Serialiser_RdfXml extends EasyRdf_Serialiser {
  private $outputtedResources = array();

  /** A constant for the RDF Type property URI */
  const RDF_XML_LITERAL = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral';

  /**
   * Protected method to serialise an object node into an XML object
   * @ignore
   */
  protected function rdfxmlObject($property, $obj, $depth) {
    $indent = str_repeat('  ', $depth);
    if ($property[0] === ':') {
      $property = substr($property, 1);
    }
    if (is_object($obj) and $obj instanceof EasyRdf_Resource) {
      $pcount = count($obj
        ->propertyUris());
      $rpcount = $this
        ->reversePropertyCount($obj);
      $alreadyOutput = isset($this->outputtedResources[$obj
        ->getUri()]);
      $tag = "{$indent}<{$property}";
      if ($obj
        ->isBNode()) {
        if ($alreadyOutput or $rpcount > 1 or $pcount == 0) {
          $tag .= " rdf:nodeID=\"" . htmlspecialchars($obj
            ->getBNodeId()) . '"';
        }
      }
      else {
        if ($alreadyOutput or $rpcount != 1 or $pcount == 0) {
          $tag .= " rdf:resource=\"" . htmlspecialchars($obj
            ->getURI()) . '"';
        }
      }
      if ($alreadyOutput == false and $rpcount == 1 and $pcount > 0) {
        $xml = $this
          ->rdfxmlResource($obj, false, $depth + 1);
        if ($xml) {
          return "{$tag}>{$xml}{$indent}</{$property}>\n\n";
        }
        else {
          return '';
        }
      }
      else {
        return $tag . "/>\n";
      }
    }
    elseif (is_object($obj) and $obj instanceof EasyRdf_Literal) {
      $atrributes = "";
      $datatype = $obj
        ->getDatatypeUri();
      if ($datatype) {
        if ($datatype == self::RDF_XML_LITERAL) {
          $atrributes .= " rdf:parseType=\"Literal\"";
          $value = strval($obj);
        }
        else {
          $datatype = htmlspecialchars($datatype);
          $atrributes .= " rdf:datatype=\"{$datatype}\"";
        }
      }
      elseif ($obj
        ->getLang()) {
        $atrributes .= ' xml:lang="' . htmlspecialchars($obj
          ->getLang()) . '"';
      }

      // Escape the value
      if (!isset($value)) {
        $value = htmlspecialchars(strval($obj));
      }
      return "{$indent}<{$property}{$atrributes}>{$value}</{$property}>\n";
    }
    else {
      throw new EasyRdf_Exception("Unable to serialise object to xml: " . getType($obj));
    }
  }

  /**
   * Protected method to serialise a whole resource and its properties
   * @ignore
   */
  protected function rdfxmlResource($res, $showNodeId, $depth = 1) {

    // Keep track of the resources we have already serialised
    if (isset($this->outputtedResources[$res
      ->getUri()])) {
      return '';
    }
    else {
      $this->outputtedResources[$res
        ->getUri()] = true;
    }

    // If the resource has no properties - don't serialise it
    $properties = $res
      ->propertyUris();
    if (count($properties) == 0) {
      return '';
    }
    $type = $res
      ->type();
    if ($type) {
      $this
        ->addPrefix($type);
    }
    else {
      $type = 'rdf:Description';
    }
    $indent = str_repeat('  ', $depth);
    $xml = "\n{$indent}<{$type}";
    if ($res
      ->isBNode()) {
      if ($showNodeId) {
        $xml .= ' rdf:nodeID="' . htmlspecialchars($res
          ->getBNodeId()) . '"';
      }
    }
    else {
      $xml .= ' rdf:about="' . htmlspecialchars($res
        ->getUri()) . '"';
    }
    $xml .= ">\n";
    if ($res instanceof EasyRdf_Container) {
      foreach ($res as $item) {
        $xml .= $this
          ->rdfxmlObject('rdf:li', $item, $depth + 1);
      }
    }
    else {
      foreach ($properties as $property) {
        $short = EasyRdf_Namespace::shorten($property, true);
        if ($short) {
          $this
            ->addPrefix($short);
          $objects = $res
            ->all("<{$property}>");
          if ($short == 'rdf:type' && $type != 'rdf:Description') {
            array_shift($objects);
          }
          foreach ($objects as $object) {
            $xml .= $this
              ->rdfxmlObject($short, $object, $depth + 1);
          }
        }
        else {
          throw new EasyRdf_Exception("It is not possible to serialse the property " . "'{$property}' to RDF/XML.");
        }
      }
    }
    $xml .= "{$indent}</{$type}>\n";
    return $xml;
  }

  /**
   * Method to serialise an EasyRdf_Graph to RDF/XML
   *
   * @param EasyRdf_Graph $graph   An EasyRdf_Graph object.
   * @param string        $format  The name of the format to convert to.
   * @param array         $options
   * @throws EasyRdf_Exception
   * @return string The RDF in the new desired format.
   */
  public function serialise($graph, $format, array $options = array()) {
    parent::checkSerialiseParams($graph, $format);
    if ($format != 'rdfxml') {
      throw new EasyRdf_Exception("EasyRdf_Serialiser_RdfXml does not support: {$format}");
    }

    // store of namespaces to be appended to the rdf:RDF tag
    $this->prefixes = array(
      'rdf' => true,
    );

    // store of the resource URIs we have serialised
    $this->outputtedResources = array();
    $xml = '';

    // Serialise URIs first
    foreach ($graph
      ->resources() as $resource) {
      if (!$resource
        ->isBnode()) {
        $xml .= $this
          ->rdfxmlResource($resource, true);
      }
    }

    // Serialise bnodes afterwards
    foreach ($graph
      ->resources() as $resource) {
      if ($resource
        ->isBnode()) {
        $xml .= $this
          ->rdfxmlResource($resource, true);
      }
    }

    // iterate through namepsaces array prefix and output a string.
    $namespaceStr = '';
    foreach ($this->prefixes as $prefix => $count) {
      $url = EasyRdf_Namespace::get($prefix);
      if (strlen($namespaceStr)) {
        $namespaceStr .= "\n        ";
      }
      if (strlen($prefix) === 0) {
        $namespaceStr .= ' xmlns="' . htmlspecialchars($url) . '"';
      }
      else {
        $namespaceStr .= ' xmlns:' . $prefix . '="' . htmlspecialchars($url) . '"';
      }
    }
    return "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n" . "<rdf:RDF" . $namespaceStr . ">\n" . $xml . "\n</rdf:RDF>\n";
  }

}

Classes

Namesort descending Description
EasyRdf_Serialiser_RdfXml Class to serialise an EasyRdf_Graph to RDF/XML with no external dependancies.