Skip to content

Commit 462a75d

Browse files
authored
Merge pull request #87 from samipuro/fix/qpxml-pi-prefix
Fix `QPXML::pi($prefix)` always returning NULL
1 parent 84b28f8 commit 462a75d

3 files changed

Lines changed: 14 additions & 10 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ QueryPath Changelog
2020
- Fix processing instructions gaining an extra `?` each time an HTML-parsed document was serialized, so `<?php echo $title; ?>` came back out of `html()`, `innerHTML()`, `innerXML()`, `innerXHTML()`, `xml()`, `html5()`, `innerHTML5()`, and `writeXML()` as `<?php echo $title; ??>`. libxml's HTML parser keeps the closing `?` as part of the node's data, unlike its XML parser and the Masterminds HTML5 parser, so QueryPath now strips it on load. `DOMProcessingInstruction::$data` consequently no longer has a stray `?` on the end for documents read with `htmlqp()` or `qp()` on an `.html` file. Note that this normalisation applies only to documents QueryPath parses itself, and that taking the underlying `DOMDocument` out of QueryPath and calling libxml's own `saveHTML()` on it will emit `<?php ... >` without the terminator, since libxml's HTML serializer never adds one
2121
- With libxml2 2.14+, `htmlqp()` parses `<?php ... ?>` as a comment (`<!--?php ... ?-->`) and no longer throws `QueryPath\ParseException` on malformed HTML. Use `html5qp()` to keep processing instructions
2222
- Add `QueryPath\Document`, a `DOMDocument` subclass QueryPath parses into. The type is how QueryPath records that a document's processing instruction data does not carry the closing `?`, which cannot be determined by inspecting the document afterwards. It travels with the document, so every route to a second `DOMQuery` over one document -- iteration, `add()`, `remove()`, `replaceAll()`, `branch()`, `QueryPath::with()`, and the bundled extensions -- serializes it correctly. A `DOMDocument` supplied by the caller is a plain `DOMDocument`, makes no such promise, and is still serialized exactly as it was handed over
23+
- Fix `QPXML::pi($prefix)` always returning `NULL` with an "Undefined property" warning instead of the matching processing instruction's text (issue #79)
2324
- Fix fatal error when running a CSS selector against a match set that contains non-element nodes (text, comment, CDATA or processing instruction), as `contents()` returns. Those nodes now simply do not match, instead of calling element-only DOM methods on them
2425
- Fix `find('a > b')` throwing a `TypeError` when the left-hand side matched the root element, whose parent is the document rather than an element
2526
- Fix the `:text` pseudo-class so it matches jQuery: it selects `input` elements whose `type` attribute is absent or is `text` (case-insensitively). It never indicated, and still does not indicate, whether a node is a text node

‎src/Extension/QPXML.php‎

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -142,15 +142,8 @@ public function pi($prefix = null, $text = null)
142142
}
143143
foreach ($this->qp->get() as $ele) {
144144
foreach ($ele->childNodes as $node) {
145-
if ($node->nodeType == XML_PI_NODE) {
146-
if (isset($prefix)) {
147-
if ($node->tagName == $prefix) {
148-
return $node->textContent;
149-
}
150-
} else {
151-
// Return first match.
152-
return $node->textContent;
153-
}
145+
if ($node->nodeType == XML_PI_NODE && ($prefix === null || $node->target === $prefix)) {
146+
return $node->textContent;
154147
}
155148
} // foreach
156149
} // foreach

‎tests/QueryPath/Extension/QPXMLTest.php‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,16 @@ public function testProcessingInstruction()
3939
{
4040
$this->assertEquals('This is a processing instruction.', trim(qp($this->file, 'third')->pi()));
4141
$msg = "Message";
42-
$this->assertEquals($msg, qp($this->file, 'second')->pi('qp', $msg)->top()->find('second')->pi());
42+
$this->assertEquals($msg, qp($this->file, 'second')->pi('qp', $msg)->top()->find('second')->pi('qp'));
43+
}
44+
45+
public function testProcessingInstructionByPrefix()
46+
{
47+
$xml = '<?xml version="1.0"?><root><?first one?><?second two?></root>';
48+
49+
$qp = qp($xml, 'root');
50+
51+
$this->assertEquals('two', $qp->pi('second'));
52+
$this->assertNull($qp->pi('missing'));
4353
}
4454
}

0 commit comments

Comments
 (0)