Skip to content

Commit

Permalink
Refactor addXPath
Browse files Browse the repository at this point in the history
Factor out some functionality of addXPath into private helper method parseFragment()
  • Loading branch information
chadicus committed Jun 2, 2015
1 parent 0f4b00f commit 3d2cc78
Showing 1 changed file with 39 additions and 26 deletions.
65 changes: 39 additions & 26 deletions src/DOMDocument.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,7 @@ public static function toArray(\DOMDocument $document)
*/
public static function addXPath(\DOMDocument $document, $xpath, $value = null)
{
$pointer = $document;
$domXPath = new \DOMXPath($document);

$list = @$domXPath->query($xpath);
if ($list === false) {
throw new \DOMException("XPath {$xpath} is not valid.");
Expand All @@ -68,37 +66,52 @@ public static function addXPath(\DOMDocument $document, $xpath, $value = null)
return;
}

$pointer = $document;
foreach (array_filter(explode('/', $xpath)) as $tagName) {
$count = 1;
$matches = [];
if (preg_match('/^(?P<parent>[a-z][\w0-9-]*)\[(?P<child>[a-z][\w0-9-]*)\s*=\s*"(?P<value>.*)"\]$/i', $tagName, $matches)) {
$child = $document->createElement($matches['child'], $matches['value']);
$parent = $document->createElement($matches['parent']);
$parent->appendChild($child);
$pointer->appendChild($parent);
$pointer = $parent;
continue;
}
$pointer = self::parseFragment($domXPath, $pointer, $tagName);
}

if (preg_match('/^(?P<name>[a-z][\w0-9-]*)\[(?P<count>\d+)\]$/i', $tagName, $matches)) {
$tagName = $matches['name'];
$count = $matches['count'];
}
$pointer->nodeValue = $value;
}

if ($tagName[0] === '@') {
$attribute = $document->createAttribute(substr($tagName, 1));
$pointer->appendChild($attribute);
$pointer = $attribute;
continue;
}
/**
* Helper method to create element(s) from the given tagName.
*
* @param \domXPath $domXPath The DOMXPath object built using the owner document.
* @param \DOMNode $context The node to which the new elements will be added.
* @param string $tagName The tag name of the element.
*
* @return \DOMNode The new context node
*/
private static function parseFragment(\DOMXPath $domXPath, \DOMNode $context, $tagName)
{
$document = $context instanceof \DOMDocument ? $context : $context->ownerDocument;

$list = $domXPath->query($tagName, $pointer);
self::addMultiple($document, $pointer, $tagName, $count - $list->length);
if ($tagName[0] === '@') {
$attribute = $document->createAttribute(substr($tagName, 1));
$context->appendChild($attribute);
return $attribute;
}

$pointer = $domXPath->query($tagName, $pointer)->item($count - 1);
$matches = [];
if (preg_match('/^(?P<parent>[a-z][\w0-9-]*)\[(?P<child>[a-z][\w0-9-]*)\s*=\s*"(?P<value>.*)"\]$/i', $tagName, $matches)) {
$parent = $document->createElement($matches['parent']);
$parent->appendChild($document->createElement($matches['child'], $matches['value']));
$context->appendChild($parent);
return $parent;
}

$pointer->nodeValue = $value;
$matches = [];
preg_match('/^(?P<name>[a-z][\w0-9-]*)\[(?P<count>\d+)\]$/i', $tagName, $matches);
$matches += ['count' => 1, 'name' => $tagName];

$count = $matches['count'];
$tagName = $matches['name'];

$list = $domXPath->query($tagName, $context);
self::addMultiple($document, $context, $tagName, $count - $list->length);

return $domXPath->query($tagName, $context)->item($count - 1);
}

/**
Expand Down

0 comments on commit 3d2cc78

Please sign in to comment.