%PDF- %PDF-
| Direktori : /www/varak.net/wiki.varak.net/vendor/wikimedia/purtle/src/ |
| Current File : /www/varak.net/wiki.varak.net/vendor/wikimedia/purtle/src/XmlRdfWriter.php |
<?php
namespace Wikimedia\Purtle;
use InvalidArgumentException;
/**
* XML/RDF implementation of RdfWriter
*
* @license GPL-2.0-or-later
* @author Daniel Kinzler
*/
class XmlRdfWriter extends RdfWriterBase {
/**
* @param string $role
* @param BNodeLabeler|null $labeler
*/
public function __construct( $role = parent::DOCUMENT_ROLE, BNodeLabeler $labeler = null ) {
parent::__construct( $role, $labeler );
$this->transitionTable[self::STATE_START][self::STATE_DOCUMENT] = function () {
$this->beginDocument();
};
$this->transitionTable[self::STATE_DOCUMENT][self::STATE_FINISH] = function () {
$this->finishDocument();
};
$this->transitionTable[self::STATE_OBJECT][self::STATE_DOCUMENT] = function () {
$this->finishSubject();
};
$this->transitionTable[self::STATE_OBJECT][self::STATE_SUBJECT] = function () {
$this->finishSubject();
};
}
/**
* @param string $text
*
* @return string
*/
private function escape( $text ) {
return htmlspecialchars( $text, ENT_QUOTES );
}
protected function expandSubject( &$base, &$local ) {
$this->expandQName( $base, $local );
}
protected function expandPredicate( &$base, &$local ) {
$this->expandShorthand( $base, $local );
}
protected function expandResource( &$base, &$local ) {
$this->expandQName( $base, $local );
}
protected function expandType( &$base, &$local ) {
$this->expandQName( $base, $local );
}
/**
* @param string $ns
* @param string $name
* @param string[] $attributes
* @param string|null $content
*/
private function tag( $ns, $name, $attributes = [], $content = null ) {
$sep = $ns === '' ? '' : ':';
$this->write( '<' . $ns . $sep . $name );
foreach ( $attributes as $attr => $value ) {
if ( is_int( $attr ) ) {
// positional array entries are passed verbatim, may be callbacks.
$this->write( $value );
continue;
}
$this->write( " $attr=\"" . $this->escape( $value ) . '"' );
}
if ( $content === null ) {
$this->write( '>' );
} elseif ( $content === '' ) {
$this->write( '/>' );
} else {
$this->write( '>' . $content );
$this->close( $ns, $name );
}
}
/**
* @param string $ns
* @param string $name
*/
private function close( $ns, $name ) {
$sep = $ns === '' ? '' : ':';
$this->write( '</' . $ns . $sep . $name . '>' );
}
/**
* Generates an attribute list, containing the attribute given by $name, or rdf:nodeID
* if $target is a blank node id (starting with "_:"). If $target is a qname, an attempt
* is made to resolve it into a full IRI based on the namespaces registered by calling
* prefix().
*
* @param string $name the attribute name (without the 'rdf:' prefix)
* @param string|null $base
* @param string|null $local
*
* @throws InvalidArgumentException
* @return string[]
*/
private function getTargetAttributes( $name, $base, $local ) {
if ( $base === null && $local === null ) {
return [];
}
// handle blank
if ( $base === '_' ) {
$name = 'nodeID';
$value = $local;
} elseif ( $local !== null ) {
throw new InvalidArgumentException( "Expected IRI, got QName: $base:$local" );
} else {
$value = $base;
}
return [
"rdf:$name" => $value
];
}
/**
* Emit a document header.
*/
private function beginDocument() {
$this->write( "<?xml version=\"1.0\"?>\n" );
// define a callback for generating namespace attributes
$namespaceAttrCallback = function () {
$attr = '';
$namespaces = $this->getPrefixes();
foreach ( $namespaces as $ns => $uri ) {
$escapedUri = htmlspecialchars( $uri, ENT_QUOTES );
$nss = $ns === '' ? '' : ":$ns";
$attr .= " xmlns$nss=\"$escapedUri\"";
}
return $attr;
};
$this->tag( 'rdf', 'RDF', [ $namespaceAttrCallback ] );
$this->write( "\n" );
}
/**
* @param string $base
* @param string|null $local
*/
protected function writeSubject( $base, $local = null ) {
$attr = $this->getTargetAttributes( 'about', $base, $local );
$this->write( "\t" );
$this->tag( 'rdf', 'Description', $attr );
$this->write( "\n" );
}
/**
* Emit the root element
*/
private function finishSubject() {
$this->write( "\t" );
$this->close( 'rdf', 'Description' );
$this->write( "\n" );
}
/**
* Write document footer
*/
private function finishDocument() {
// close document element
$this->close( 'rdf', 'RDF' );
$this->write( "\n" );
}
/**
* @param string $base
* @param string|null $local
*/
protected function writePredicate( $base, $local = null ) {
// noop
}
/**
* @param string $base
* @param string|null $local
*/
protected function writeResource( $base, $local = null ) {
$attr = $this->getTargetAttributes( 'resource', $base, $local );
$this->write( "\t\t" );
$this->tag( $this->currentPredicate[0], $this->currentPredicate[1], $attr, '' );
$this->write( "\n" );
}
/**
* @param string $text
* @param string|null $language
*/
protected function writeText( $text, $language = null ) {
$attr = $this->isValidLanguageCode( $language )
? [ 'xml:lang' => $language ]
: [];
$this->write( "\t\t" );
$this->tag(
$this->currentPredicate[0],
$this->currentPredicate[1],
$attr,
$this->escape( $text )
);
$this->write( "\n" );
}
/**
* @param string $literal
* @param string|null $typeBase
* @param string|null $typeLocal
*/
public function writeValue( $literal, $typeBase, $typeLocal = null ) {
$attr = $this->getTargetAttributes( 'datatype', $typeBase, $typeLocal );
$this->write( "\t\t" );
$this->tag(
$this->currentPredicate[0],
$this->currentPredicate[1],
$attr,
$this->escape( $literal )
);
$this->write( "\n" );
}
/**
* @param string $role
* @param BNodeLabeler $labeler
*
* @return RdfWriterBase
*/
protected function newSubWriter( $role, BNodeLabeler $labeler ) {
$writer = new self( $role, $labeler );
return $writer;
}
/**
* @return string a MIME type
*/
public function getMimeType() {
return 'application/rdf+xml; charset=UTF-8';
}
}