]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blobdiff - vendor/wikimedia/purtle/src/XmlRdfWriter.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / vendor / wikimedia / purtle / src / XmlRdfWriter.php
diff --git a/vendor/wikimedia/purtle/src/XmlRdfWriter.php b/vendor/wikimedia/purtle/src/XmlRdfWriter.php
new file mode 100644 (file)
index 0000000..74a1132
--- /dev/null
@@ -0,0 +1,223 @@
+<?php
+
+namespace Wikimedia\Purtle;
+
+use InvalidArgumentException;
+
+/**
+ * XML/RDF implementation of RdfWriter
+ *
+ * @license GPL-2.0+
+ * @author Daniel Kinzler
+ */
+class XmlRdfWriter extends RdfWriterBase {
+
+       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();
+               };
+       }
+
+       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 );
+       }
+
+       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 );
+               }
+       }
+
+       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" );
+       }
+
+       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" );
+       }
+
+       protected function writePredicate( $base, $local = null ) {
+               // noop
+       }
+
+       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" );
+       }
+
+       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" );
+       }
+
+       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';
+       }
+
+}