Skip to content

Commit

Permalink
Added simple parser base
Browse files Browse the repository at this point in the history
  • Loading branch information
jkphl committed Feb 14, 2017
1 parent fd9f2c0 commit c973b92
Show file tree
Hide file tree
Showing 7 changed files with 272 additions and 92 deletions.
9 changes: 0 additions & 9 deletions src/Rdfalite/Application/Parser/DOMIterator.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,4 @@ public function rewind()
{
parent::rewind();
}

/**
* Return the context in it's current state
*
* @return Context Context
*/
public function getContext() {
return $this->initialContext;
}
}
27 changes: 11 additions & 16 deletions src/Rdfalite/Application/Parser/Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@

use Jkphl\Rdfalite\Application\Contract\DocumentFactoryInterface;
use Jkphl\Rdfalite\Application\Contract\ElementProcessorInterface;
use Jkphl\Rdfalite\Domain\Thing\ThingInterface;


/**
Expand Down Expand Up @@ -76,27 +77,21 @@ public function __construct(DocumentFactoryInterface $documentFactory, ElementPr
/**
* Parse a string
*
* @param string $string String
* @return mixed
* @param string $string Parseable string
* @return ThingInterface[] Parsed things
*/
public function parse($string)
{
// $document = $this->documentFactory->createDocumentFromString($string);
// $context = new Context();
// $iterator = new DOMIterator($document->childNodes, $context, $this->elementProcessor);
$document = $this->documentFactory->createDocumentFromString($string);
$context = new Context();
$iterator = new DOMIterator($document->childNodes, $context, $this->elementProcessor);

/**
* Recursively run through all child elements
*
* @var \DOMElement $element
*/
// foreach ($iterator->getRecursiveIterator() as $element) {
// if ($element instanceof \DOMElement) {
// $this->elementProcessor->processElement($element, $this);
// }
// }
// Iterate through all $node
foreach ($iterator->getRecursiveIterator() as $node) {
$node || true;
}

return null;
return $context->getChildren();
}
}

61 changes: 61 additions & 0 deletions src/Rdfalite/Infrastructure/Factories/HtmlDocumentFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

/**
* rdfa-lite
*
* @category Jkphl
* @package Jkphl\Rdfalite
* @subpackage Jkphl\Rdfalite\Infrastructure
* @author Joschi Kuphal <joschi@tollwerk.de> / @jkphl
* @copyright Copyright © 2017 Joschi Kuphal <joschi@tollwerk.de> / @jkphl
* @license http://opensource.org/licenses/MIT The MIT License (MIT)
*/

/***********************************************************************************
* The MIT License (MIT)
*
* Copyright © 2017 Joschi Kuphal <joschi@kuphal.net> / @jkphl
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
***********************************************************************************/

namespace Jkphl\Rdfalite\Infrastructure\Factories;

use Jkphl\Rdfalite\Application\Contract\DocumentFactoryInterface;

/**
* HTML document factory
*
* @package Jkphl\Rdfalite
* @subpackage Jkphl\Rdfalite\Infrastructure
*/
class HtmlDocumentFactory implements DocumentFactoryInterface
{
/**
* Create a DOM document from a string
*
* @param string $string String
* @return \DOMDocument DOM document
*/
public function createDocumentFromString($string)
{
$dom = new \DOMDocument();
$dom->loadHTML($string);
return $dom;
}
}
22 changes: 17 additions & 5 deletions src/Rdfalite/Infrastructure/Parser/RdfaliteElementProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -141,8 +141,11 @@ protected function processProperty(\DOMElement $element, Context $context)
// Determine the vocabulary to use
$vocabulary = empty($prefix) ? $context->getDefaultVocabulary() : $context->getVocabulary($prefix);
if ($vocabulary instanceof VocabularyInterface) {
// Try to get a resource ID
$resourceId = trim($element->getAttribute('resource')) ?: null;

// Add the property to the current parent thing
$property = new Property($name, $vocabulary, $this->getPropertyValue($element, $context));
$property = new Property($name, $vocabulary, $this->getPropertyValue($element, $context), $resourceId);
$context->getParentThing()->addProperty($property);
}
}
Expand All @@ -161,7 +164,11 @@ protected function getPropertyValue(\DOMElement $element, Context $context)
{
// If the property creates a new type: Return the element itself
if ($element->hasAttribute('typeof')) {
return $this->getThing($element->getAttribute('typeof'), $context);
return $this->getThing(
$element->getAttribute('typeof'),
trim($element->getAttribute('resource')) ?: null,
$context
);
}

// Else: Depend on the tag name
Expand Down Expand Up @@ -200,12 +207,13 @@ protected function getPropertyValue(\DOMElement $element, Context $context)
* Return a property value (type and tag name dependent)
*
* @param string $typeof Thing type
* @param string $resourceId Resource ID
* @param Context $context Context
* @return ThingInterface Thing
* @throws OutOfBoundsException If the default vocabulary is empty
* @throws OutOfBoundsException If the vocabulary prefix is unknown
*/
protected function getThing($typeof, Context $context)
protected function getThing($typeof, $resourceId, Context $context)
{
$typeof = explode(':', $typeof);
$type = array_pop($typeof);
Expand All @@ -215,7 +223,7 @@ protected function getThing($typeof, Context $context)
$vocabulary = empty($prefix) ? $context->getDefaultVocabulary() : $context->getVocabulary($prefix);
if ($vocabulary instanceof VocabularyInterface) {
// Return a new thing
return new Thing($type, $vocabulary);
return new Thing($type, $vocabulary, $resourceId);
}

// If the default vocabulary is empty
Expand All @@ -242,7 +250,11 @@ protected function getThing($typeof, Context $context)
protected function processTypeof(\DOMElement $element, Context $context)
{
if ($element->hasAttribute('typeof')) {
$thing = $this->getThing($element->getAttribute('typeof'), $context);
$thing = $this->getThing(
$element->getAttribute('typeof'),
trim($element->getAttribute('resource')) ?: null,
$context
);

if ($thing instanceof ThingInterface) {
// Add the new thing as a child to the current context
Expand Down
64 changes: 2 additions & 62 deletions src/Rdfalite/Tests/Application/DOMIteratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,39 +39,16 @@
use Jkphl\Rdfalite\Application\Contract\ElementProcessorInterface;
use Jkphl\Rdfalite\Application\Parser\Context;
use Jkphl\Rdfalite\Application\Parser\DOMIterator;
use Jkphl\Rdfalite\Domain\Property\Property;
use Jkphl\Rdfalite\Domain\Property\PropertyInterface;
use Jkphl\Rdfalite\Domain\Thing\ThingInterface;
use Jkphl\Rdfalite\Domain\Vocabulary\Vocabulary;
use Jkphl\Rdfalite\Infrastructure\Parser\RdfaliteElementProcessor;
use Jkphl\Rdfalite\Tests\Domain\VocabularyTest;

/**
* DOM node iterator tests
*
* @package Jkphl\Rdfalite
* @subpackage Jkphl\Rdfalite\Tests
*/
class DOMNodeIteratorTest extends \PHPUnit_Framework_TestCase
class DOMNodeIteratorTest extends ParserIteratorTestBase
{
/**
* Test HTML
*
* @var string
*/
protected static $html;


/**
* Setup all tests
*/
public static function setUpBeforeClass()
{
self::$html = file_get_contents(
dirname(__DIR__).DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'rdfa-lite-1.1.html'
);
}

/**
* Test recursive DOM node iteration
*/
Expand Down Expand Up @@ -129,43 +106,6 @@ public function testRdfaLiteProcessor()
}
}
$this->assertEquals(0, count($elements));
$things = $context->getChildren();
$schemaOrgVocabulary = new Vocabulary(VocabularyTest::SCHEMA_ORG);

$this->assertTrue(is_array($things));
$this->assertEquals(1, count($things));
$thing = $things[0];

$this->assertInstanceOf(ThingInterface::class, $thing);
$this->assertEquals(VocabularyTest::SCHEMA_ORG.'Person', $thing->getType());
$this->assertEquals($schemaOrgVocabulary, $thing->getVocabulary());

$properties = $thing->getProperties();
$this->assertTrue(is_array($properties));
$this->assertEquals(4, count($properties));

$name = $thing->getProperty('name');
$this->assertTrue(is_array($name));
$this->assertEquals(1, count($name));
$this->assertInstanceOf(PropertyInterface::class, $name[0]);
$this->assertEquals(new Property('name', $schemaOrgVocabulary, 'Joschi Kuphal'), $name[0]);

$telephone = $thing->getProperty('telephone');
$this->assertTrue(is_array($telephone));
$this->assertEquals(1, count($telephone));
$this->assertInstanceOf(PropertyInterface::class, $telephone[0]);
$this->assertEquals(new Property('telephone', $schemaOrgVocabulary, '+49 911 9593945'), $telephone[0]);

$image = $thing->getProperty('image');
$this->assertTrue(is_array($image));
$this->assertEquals(1, count($image));
$this->assertInstanceOf(PropertyInterface::class, $image[0]);
$this->assertEquals(new Property('image', $schemaOrgVocabulary, 'https://jkphl.is/avatar.jpg'), $image[0]);

$preferredAnimal = $thing->getProperty('preferredAnimal');
$this->assertTrue(is_array($preferredAnimal));
$this->assertEquals(1, count($preferredAnimal));
$this->assertInstanceOf(PropertyInterface::class, $preferredAnimal[0]);
$this->assertEquals(new Property('preferredAnimal', new Vocabulary('http://open.vocab.org/terms/'), 'Unicorn'), $preferredAnimal[0]);
$this->validateIteratorResult($context->getChildren());
}
}
117 changes: 117 additions & 0 deletions src/Rdfalite/Tests/Application/ParserIteratorTestBase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
<?php

/**
* rdfa-lite
*
* @category Jkphl
* @package Jkphl\Rdfalite
* @subpackage Jkphl\Rdfalite\Tests
* @author Joschi Kuphal <joschi@tollwerk.de> / @jkphl
* @copyright Copyright © 2017 Joschi Kuphal <joschi@tollwerk.de> / @jkphl
* @license http://opensource.org/licenses/MIT The MIT License (MIT)
*/

/***********************************************************************************
* The MIT License (MIT)
*
* Copyright © 2017 Joschi Kuphal <joschi@kuphal.net> / @jkphl
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
***********************************************************************************/

namespace Jkphl\Rdfalite\Tests\Application;

use Jkphl\Rdfalite\Domain\Property\Property;
use Jkphl\Rdfalite\Domain\Property\PropertyInterface;
use Jkphl\Rdfalite\Domain\Thing\ThingInterface;
use Jkphl\Rdfalite\Domain\Vocabulary\Vocabulary;
use Jkphl\Rdfalite\Tests\Domain\VocabularyTest;

/**
* Base class for parser & iterator tests
*
* @package Jkphl\Rdfalite
* @subpackage Jkphl\Rdfalite\Tests
*/
abstract class ParserIteratorTestBase extends \PHPUnit_Framework_TestCase
{
/**
* Test HTML
*
* @var string
*/
protected static $html;

/**
* Setup all tests
*/
public static function setUpBeforeClass()
{
self::$html = file_get_contents(
dirname(__DIR__).DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'rdfa-lite-1.1.html'
);
}

/**
* Validate parsing results
*
* @param ThingInterface[] $things Parsing Results
*/
protected function validateIteratorResult(array $things)
{
$schemaOrgVocabulary = new Vocabulary(VocabularyTest::SCHEMA_ORG);

$this->assertTrue(is_array($things));
$this->assertEquals(1, count($things));
$thing = $things[0];

$this->assertInstanceOf(ThingInterface::class, $thing);
$this->assertEquals(VocabularyTest::SCHEMA_ORG.'Person', $thing->getType());
$this->assertEquals($schemaOrgVocabulary, $thing->getVocabulary());
$this->assertEquals('#joschi', $thing->getResourceId());

$properties = $thing->getProperties();
$this->assertTrue(is_array($properties));
$this->assertEquals(4, count($properties));

$name = $thing->getProperty('name');
$this->assertTrue(is_array($name));
$this->assertEquals(1, count($name));
$this->assertInstanceOf(PropertyInterface::class, $name[0]);
$this->assertEquals(new Property('name', $schemaOrgVocabulary, 'Joschi Kuphal'), $name[0]);

$telephone = $thing->getProperty('telephone');
$this->assertTrue(is_array($telephone));
$this->assertEquals(1, count($telephone));
$this->assertInstanceOf(PropertyInterface::class, $telephone[0]);
$this->assertEquals(new Property('telephone', $schemaOrgVocabulary, '+49 911 9593945'), $telephone[0]);

$image = $thing->getProperty('image');
$this->assertTrue(is_array($image));
$this->assertEquals(1, count($image));
$this->assertInstanceOf(PropertyInterface::class, $image[0]);
$this->assertEquals(new Property('image', $schemaOrgVocabulary, 'https://jkphl.is/avatar.jpg'), $image[0]);

$preferredAnimal = $thing->getProperty('preferredAnimal');
$this->assertTrue(is_array($preferredAnimal));
$this->assertEquals(1, count($preferredAnimal));
$this->assertInstanceOf(PropertyInterface::class, $preferredAnimal[0]);
$this->assertEquals(new Property('preferredAnimal', new Vocabulary('http://open.vocab.org/terms/'), 'Unicorn'),
$preferredAnimal[0]);
}
}
Loading

0 comments on commit c973b92

Please sign in to comment.