Skip to content
This repository was archived by the owner on Oct 12, 2024. It is now read-only.

Commit 1758c78

Browse files
committed
Inital
0 parents  commit 1758c78

File tree

12 files changed

+588
-0
lines changed

12 files changed

+588
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
composer.lock
2+
vendor
3+
docs/build

README.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
DOM
2+
===
3+
4+
This library provides a wrapper for the PHP DOM library which makes your life
5+
easier.
6+
7+
It wraps the `\DOMDocument`, `\DOMElement` and `\DOMXpath` classes.`
8+
9+
Example:
10+
11+
```php
12+
$dom = new Document();
13+
$element = $dom->createRoot('example');
14+
$element->appendChild('boo', 'hello');
15+
$element->appendChild('baz', 'world');
16+
17+
echo $dom->saveXml();
18+
// <?xml version="1.0"?>
19+
// <example>
20+
// <boo>hello</boo>
21+
// <baz>world</baz>
22+
// </example>
23+
24+
$element->appendChild('number', 5);
25+
$element->appendChild('number', 10);
26+
27+
echo $element->evaluate('sum(./number)'); // 15
28+
29+
$nodeList = $element->query('./number');
30+
31+
echo $nodeList->length; // 2
32+
```
33+
34+
Document
35+
--------
36+
37+
The `PhpBench\Dom\Document` class wraps the `\DOMDocument` class and replaces the
38+
`\DOMElement` class with the `PhpBench\Dom\Element` class.
39+
40+
It implements the `XPathAware` interface.
41+
42+
- `createRoot($name, $value = null)`: Create and return a new root node with `$name` and optional
43+
`$value`.
44+
- `query($query, $context = null)`: Execute a given XPath query on the
45+
document.
46+
- `queryOne($query, $context = null)`: Execute a given XPath query on the
47+
document and return the first element or `NULL`.
48+
- `evaluate($query, $context = null)`: Evaluate the given XPath expression.
49+
50+
Element
51+
-------
52+
53+
- `appendElement($name $value)`: Create and return an element with name
54+
`$name` and value `$value`.
55+
- `query`, `queryOne` and `evalauate`: As with Document but will use the context of this element by
56+
default.

composer.json

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "phpbench/dom",
3+
"description": "DOM wrapper to simplify working with the PHP DOM implementation",
4+
"license": "MIT",
5+
"authors": [
6+
{
7+
"name": "Daniel Leech",
8+
"email": "daniel@dantleech.com"
9+
}
10+
],
11+
"require": {
12+
"php": "^5.0",
13+
"ext-dom": "*"
14+
},
15+
"require-dev": {
16+
"phpunit/phpunit": "^4.6"
17+
},
18+
"autoload": {
19+
"psr-4": {
20+
"PhpBench\\Dom\\": "lib/"
21+
}
22+
},
23+
"autoload-dev": {
24+
"psr-4": {
25+
"PhpBench\\Dom\\Tests\\": "tests/"
26+
}
27+
},
28+
"extra": {
29+
"branch-alias": {
30+
"dev-master": "1.0-dev"
31+
}
32+
}
33+
}

lib/Document.php

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the PHPBench package
5+
*
6+
* (c) Daniel Leech <daniel@dantleech.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace PhpBench\Dom;
13+
14+
use PhpBench\Dom\Element;
15+
use PhpBench\Dom\XPath;
16+
use PhpBench\Dom\XPathAware;
17+
18+
/**
19+
* Wrapper for the \DOMDocument class.
20+
*/
21+
class Document extends \DOMDocument implements XPathAware
22+
{
23+
/**
24+
* @var XPath
25+
*/
26+
private $xpath;
27+
28+
/**
29+
* @param string $version
30+
* @param mixed $encoding
31+
*/
32+
public function __construct($version = '1.0', $encoding = null)
33+
{
34+
parent::__construct($version, $encoding);
35+
$this->registerNodeClass('DOMElement', 'PhpBench\Dom\Element');
36+
}
37+
38+
/**
39+
* Create and return a root DOM element
40+
*
41+
* @param string $name
42+
* @return Element
43+
*/
44+
public function createRoot($name)
45+
{
46+
return $this->appendChild(new Element($name));
47+
}
48+
49+
/**
50+
* Return the XPath object bound to this document.
51+
*
52+
* @return XPath
53+
*/
54+
public function xpath()
55+
{
56+
if ($this->xpath) {
57+
return $this->xpath;
58+
}
59+
60+
$this->xpath = new XPath($this);
61+
62+
return $this->xpath;
63+
}
64+
65+
/**
66+
* {@inheritdoc}
67+
*/
68+
public function query($query, \DOMNode $context = null)
69+
{
70+
return $this->xpath()->query($query, $context);
71+
}
72+
73+
/**
74+
* {@inheritdoc}
75+
*/
76+
public function queryOne($query, \DOMNode $context = null)
77+
{
78+
return $this->xpath()->queryOne($query, $context);
79+
}
80+
81+
/**
82+
* {@inheritdoc}
83+
*/
84+
public function evaluate($expression, \DOMNode $context = null)
85+
{
86+
return $this->xpath()->evaluate($expression, $context);
87+
}
88+
}

lib/Element.php

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the PHPBench package
5+
*
6+
* (c) Daniel Leech <daniel@dantleech.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace PhpBench\Dom;
13+
14+
use PhpBench\Dom\XPathAware;
15+
16+
/**
17+
* Wrapper for the \DOMElement class.
18+
*/
19+
class Element extends \DOMElement implements XPathAware
20+
{
21+
/**
22+
* Create and append an element with the given name and optionally given value.
23+
*
24+
* @param string $name
25+
* @param mixed $value
26+
* @return Element
27+
*/
28+
public function appendElement($name, $value = null)
29+
{
30+
return $this->appendChild(new self($name, $value));
31+
}
32+
33+
/**
34+
* {@inheritdoc}
35+
*/
36+
public function query($xpath, \DOMNode $context = null)
37+
{
38+
return $this->ownerDocument->xpath()->query($xpath, $context ?: $this);
39+
}
40+
41+
public function queryOne($xpath, \DOMNode $context = null)
42+
{
43+
return $this->ownerDocument->xpath()->queryOne($xpath, $context ?: $this);
44+
}
45+
46+
/**
47+
* {@inheritdoc}
48+
*/
49+
public function evaluate($expression, \DOMNode $context = null)
50+
{
51+
return $this->ownerDocument->xpath()->evaluate($expression, $context ?: $this);
52+
}
53+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace PhpBench\Dom\Exception;
4+
5+
class InvalidQueryException extends \InvalidArgumentException
6+
{
7+
}

lib/XPath.php

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Tabular package
5+
*
6+
* (c) Daniel Leech <daniel@dantleech.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace PhpBench\Dom;
13+
14+
/**
15+
* Wrapper for the \DOMXPath class.
16+
*/
17+
class XPath extends \DOMXPath
18+
{
19+
/**
20+
* {@inheritdoc}
21+
*/
22+
public function evaluate($expr, \DOMNode $contextEl = null, $registerNodeNs = null)
23+
{
24+
$result = $this->execute('evaluate', 'expression', $expr, $contextEl, $registerNodeNs);
25+
return $result;
26+
}
27+
28+
/**
29+
* {@inheritdoc}
30+
*/
31+
public function query($expr, \DOMNode $contextEl = null, $registerNodeNs = null)
32+
{
33+
return $this->execute('query', 'query', $expr, $contextEl, $registerNodeNs);
34+
}
35+
36+
/**
37+
* Query for one node
38+
*/
39+
public function queryOne($expr, \DOMNode $contextEl = null, $registerNodeNs = null)
40+
{
41+
$nodeList = $this->query($expr, $contextEl, $registerNodeNs);
42+
43+
if (0 === $nodeList->length) {
44+
return null;
45+
}
46+
47+
return $nodeList->item(0);
48+
}
49+
50+
/**
51+
* Execute the given xpath method and cactch any errors.
52+
*/
53+
private function execute($method, $context, $query, \DOMNode $contextEl = null, $registerNodeNs)
54+
{
55+
libxml_use_internal_errors(true);
56+
57+
$value = @parent::$method($query, $contextEl, $registerNodeNs);
58+
59+
if (false === $value) {
60+
$xmlErrors = libxml_get_errors();
61+
$errors = array();
62+
foreach ($xmlErrors as $xmlError) {
63+
$errors[] = sprintf('[%s] %s', $xmlError->code, $xmlError->message);
64+
}
65+
66+
throw new Exception\InvalidQueryException(sprintf(
67+
'Errors encountered when evaluating XPath %s "%s": %s%s',
68+
$context, $query, PHP_EOL, implode(PHP_EOL, $errors)
69+
));
70+
}
71+
72+
libxml_use_internal_errors(false);
73+
74+
return $value;
75+
}
76+
}

lib/XPathAware.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace PhpBench\Dom;
4+
5+
interface XPathAware
6+
{
7+
/**
8+
* Perform an xpath query on this document, optionally with
9+
* the given context node.
10+
*
11+
* If this interface is applied to an Element, then the element
12+
* should be used as the context if no context is given.
13+
*
14+
* @param string $query
15+
* @param \DOMNode $context
16+
* @return \DOMNodeList
17+
*/
18+
public function query($query, \DOMNode $context = null);
19+
20+
/**
21+
* As with XPathAware::query but return a single node or NULL if no node was found.
22+
*
23+
* @param string $query
24+
* @param \DOMNode $context
25+
* @return Element|null
26+
*/
27+
public function queryOne($query, \DOMNode $context = null);
28+
29+
/**
30+
* Evaluate an XPath expression on this document, optionally
31+
* with the given context node.
32+
*
33+
* If this interface is applied to an Element, then the element
34+
* should be used as the context if no context is given.
35+
*
36+
* @param string $expression
37+
* @param \DOMNode $context
38+
* @return mixed
39+
*/
40+
public function evaluate($expression, \DOMNode $context = null);
41+
}

phpunit.xml.dist

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
3+
<!-- http://www.phpunit.de/manual/current/en/appendixes.configuration.html -->
4+
<phpunit
5+
colors="true"
6+
bootstrap="vendor/autoload.php"
7+
>
8+
9+
<testsuites>
10+
<testsuite name="PhpBench DOM Test Suite">
11+
<directory>./tests</directory>
12+
</testsuite>
13+
</testsuites>
14+
15+
<filter>
16+
<whitelist addUncoveredFilesFromWhitelist="true">
17+
<directory>.</directory>
18+
<exclude>
19+
<directory>vendor/</directory>
20+
</exclude>
21+
</whitelist>
22+
</filter>
23+
24+
</phpunit>

0 commit comments

Comments
 (0)