Skip to content
This repository has been archived by the owner on Jan 29, 2020. It is now read-only.

Commit

Permalink
Merge branch 'hotfix/21'
Browse files Browse the repository at this point in the history
Close #21
  • Loading branch information
weierophinney committed Apr 9, 2018
2 parents 6ff0f94 + 863e582 commit 78e18d9
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 16 deletions.
18 changes: 10 additions & 8 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,21 @@ All notable changes to this project will be documented in this file, in reverse

### Fixed

- Nothing.
- [#21](https://github.com/zendframework/zend-dom/pull/21) fixes an issue with
matching against nested attribute selectors (e.g., `div[class="foo"] div
[class="bar"]`), ensuring such syntax will transform to expected XPath.

## 2.7.0 - 2018-03-27

### Added

- [#20](https://github.com/zendframework/zend-dom/pull/4) adds support for
- [#20](https://github.com/zendframework/zend-dom/pull/20) adds support for
attribute selectors that contain spaces, such as `input[value="Marty McFly"]`.
Previously, spaces within the selector value would result in a query per
space-separated word; they now, correctly, result in a single query for the
exact value.

- [#19](https://github.com/zendframework/zend-dom/pull/4) adds support for PHP
- [#19](https://github.com/zendframework/zend-dom/pull/19) adds support for PHP
versions 7.1 and 7.2.

- Adds documentation and publishes it to https://docs.zendframework.com/zend-dom/
Expand All @@ -45,12 +47,12 @@ All notable changes to this project will be documented in this file, in reverse

### Removed

- [#13](https://github.com/zendframework/zend-dom/pull/4) and
[#19](https://github.com/zendframework/zend-dom/pull/4) remove support for PHP
- [#13](https://github.com/zendframework/zend-dom/pull/13) and
[#19](https://github.com/zendframework/zend-dom/pull/19) remove support for PHP
versions prior to 5.6.

- [#13](https://github.com/zendframework/zend-dom/pull/4) and
[#19](https://github.com/zendframework/zend-dom/pull/4) remove support for HHVM.
- [#13](https://github.com/zendframework/zend-dom/pull/13) and
[#19](https://github.com/zendframework/zend-dom/pull/19) remove support for HHVM.

### Fixed

Expand All @@ -60,7 +62,7 @@ All notable changes to this project will be documented in this file, in reverse

### Added

- [#2](https://github.com/zendframework/zend-dom/pull/4) ads context node
- [#2](https://github.com/zendframework/zend-dom/pull/2) adds context node
support for DOMXPath->query that supports querying in the context of a
specific node.

Expand Down
16 changes: 8 additions & 8 deletions src/Document/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ public static function cssToXpath($path)

// Arbitrary attribute value contains whitespace
$path = preg_replace_callback(
'/\[\S+["\'](.+)["\']\]/',
'/\[\S+?([\'"])((?:(?!\1)[^\\\]|\\.)*)\1\]/',
function ($matches) {
return str_replace($matches[1], preg_replace('/\s+/', '\s', $matches[1]), $matches[0]);
return str_replace($matches[2], preg_replace('/\s+/', '\s', $matches[2]), $matches[0]);
},
$path
);
Expand Down Expand Up @@ -147,29 +147,29 @@ protected static function _tokenize($expression)

// arbitrary attribute strict equality
$expression = preg_replace_callback(
'|\[@?([a-z0-9_-]+)=[\'"]([^\'"]+)[\'"]\]|i',
'/\[@?([a-z0-9_-]+)=([\'"])((?:(?!\2)[^\\\]|\\.)*)\2\]/i',
function ($matches) {
return '[@' . strtolower($matches[1]) . "='" . $matches[2] . "']";
return sprintf("[@%s='%s']", strtolower($matches[1]), str_replace("'", "\\'", $matches[3]));
},
$expression
);

// arbitrary attribute contains full word
$expression = preg_replace_callback(
'|\[([a-z0-9_-]+)~=[\'"]([^\'"]+)[\'"]\]|i',
'/\[([a-z0-9_-]+)~=([\'"])((?:(?!\2)[^\\\]|\\.)*)\2\]/i',
function ($matches) {
return "[contains(concat(' ', normalize-space(@" . strtolower($matches[1]) . "), ' '), ' "
. $matches[2] . " ')]";
. $matches[3] . " ')]";
},
$expression
);

// arbitrary attribute contains specified content
$expression = preg_replace_callback(
'|\[([a-z0-9_-]+)\*=[\'"]([^\'"]+)[\'"]\]|i',
'/\[([a-z0-9_-]+)\*=([\'"])((?:(?!\2)[^\\\]|\\.)*)\2\]/i',
function ($matches) {
return "[contains(@" . strtolower($matches[1]) . ", '"
. $matches[2] . "')]";
. $matches[3] . "')]";
},
$expression
);
Expand Down
30 changes: 30 additions & 0 deletions test/Document/QueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -172,4 +172,34 @@ public function testCanTransformWithAttributeAndDot()
$test = Query::cssToXpath('a[@href="http://example.com"]');
$this->assertEquals("//a[@href='http://example.com']", $test);
}

public function nestedAttributeSelectors()
{
return [
'with-double-quotes' => [
'select[name="foo"] option[selected="selected"]',
"//select[@name='foo']//option[@selected='selected']",
],
'with-single-quotes' => [
"select[name='foo'] option[selected='selected']",
"//select[@name='foo']//option[@selected='selected']",
],
'double-quotes-containing-single-quotes' => [
"select[name=\"f'oo\"] option[selected=\"sel'ected\"]",
"//select[@name='f\'oo']//option[@selected='sel\'ected']",
],
'single-quotes-containing-double-quotes' => [
"select[name='f\"oo'] option[selected='sel\"ected']",
"//select[@name='f\"oo']//option[@selected='sel\"ected']",
],
];
}

/**
* @dataProvider nestedAttributeSelectors
*/
public function testTransformNestedAttributeSelectors($selector, $expectedXpath)
{
$this->assertEquals($expectedXpath, Query::cssToXpath($selector));
}
}

0 comments on commit 78e18d9

Please sign in to comment.