public static function fromDomElement(DOMNode $domNode) { $status = new GWTSiteSyncStatus(); $xpath = new DOMXPath($domNode->ownerDocument); $contentSrc = $xpath->query($domNode->getNodePath() . "//*[local-name()='content']/@src"); $verified = $xpath->query($domNode->getNodePath() . "//*[local-name()='verified']"); $verificationMethod = $xpath->query($domNode->getNodePath() . "//*[local-name()='verification-method']"); for ($i = 0; $i < $verificationMethod->length; $i++) { $node = $verificationMethod->item($i); if (preg_match('/google([a-f0-9]+)\\.html/', $node->nodeValue, $matches)) { $status->setPageVerificationCode($matches[1]); } } if ($contentSrc->length > 0) { $status->setUrl($contentSrc->item(0)->nodeValue); } if ($verified->length > 0) { $status->setVerified(self::parseBoolean($verified->item(0)->nodeValue)); } return $status; }
/** * Create XPath * * @param \DOMNode $node * @return string */ protected function createXPath(\DOMNode $node) { $parentXPath = ''; $currentXPath = $node->getNodePath(); if ($node->parentNode !== null && !$node->isSameNode($node->parentNode)) { $parentXPath = $this->createXPath($node->parentNode); $pathParts = explode('/', $currentXPath); $currentXPath = '/' . end($pathParts); } $attributesXPath = ''; if ($node->hasAttributes()) { $attributes = []; foreach ($node->attributes as $name => $attribute) { if ($this->isIdAttribute($name)) { $attributes[] = sprintf('@%s="%s"', $name, $attribute->value); break; } } if (!empty($attributes)) { if (substr($currentXPath, -1) === ']') { $currentXPath = substr($currentXPath, 0, strrpos($currentXPath, '[')); } $attributesXPath = '[' . implode(' and ', $attributes) . ']'; } } return '/' . trim($parentXPath . $currentXPath . $attributesXPath, '/'); }
/** * @param DOMDocument $dom * @param DOMXPath $xpath * @param DOMNode $parent * @param string $name * @param string $value * @return DOMElement */ private function &addNode($dom, $xpath, $parent, $name, $value = '') { $path = explode('/', rtrim($name, '/')); $name = end($path); $ref_node = null; $context = $parent->getNodePath(); switch ($context) { case '/theme': $before = array('name', 'description', 'files', 'about', 'settings', 'thumbs', 'locales'); break; case '/theme/settings/setting': $before = array('value', 'filename', 'name', 'description', 'options'); break; case '/theme/settings/setting/options/option': $before = array('name', 'description'); break; default: $before = array(); break; } if (!empty($before)) { do { } while ($before && $name != array_shift($before)); #find next element do { if ($query = array_shift($before)) { if (empty($xpath)) { $xpath = new DOMXPath($dom); } $query = $context . '/' . $query; if (($result = $xpath->query($query)) && $result->length) { $ref_node = $result->item(0); } } } while (!$ref_node && $before); } $element = $dom->createElement($name, $value); if ($ref_node) { $element = $parent->insertBefore($element, $ref_node); } else { $element = $parent->appendChild($element); } return $element; }
private function parseClass(DOMNode $classNode) { if (!$classNode->hasAttribute('name')) { echo "class type without name: " . $classNode->getNodePath() . "\n"; return; } $class = new Ezer_XsdClass(); $class->name = $this->prefix . ucfirst($this->replaceNameChars($classNode->getAttribute('name'))); if (!$this->redefine && isset($this->classes[$class->name])) { echo $class->name . " already exists, make sure that classes are the same.\n"; return; } for ($i = 0; $i < $classNode->childNodes->length; $i++) { $childNode = $classNode->childNodes->item($i); switch ($childNode->localName) { case '': if ($childNode->nodeName == '#comment') { $class->doc .= "\n{$childNode->nodeValue}"; } break; case 'anyAttribute': break; case 'annotation': $class->doc .= "\n{$childNode->nodeValue}"; break; case 'attribute': $this->parseAttribute($class, $childNode); break; case 'sequence': $this->parseSequence($class, $childNode); break; case 'complexContent': $this->parseComplexContent($class, $childNode); break; case 'choice': $this->parseChoice($class, $childNode); break; default: echo "Unhandled class property: {$childNode->localName}.\n"; break; } } $this->classes[$class->name] = $class; }
/** * Fill PHPFrontNodeList::$nodeList with DOMNodeList objects or arrays of DOMNode objects. This function is usually called by PHPFront. * * @param array $element_selectors A list of element selectors provided by PHPFront. * @param DOMNode $source_element A DOMNode element from which to source elements for the population. * @param bool $repeat_fn The repeat function to use. * @param bool $self_repeat Sets whether to fill up nodeList with repeatitions of $source_element itself or child elements. * * @see PHPFront::setElementData(). * * @return void */ public function __construct(array $element_selectors, $source_element, $repeat_fn = null, $self_repeat = false) { // Initially available elements have been populated. if (!empty($repeat_fn)) { // Add initial comma, remove all spaces $this->repeat_fn = ',' . str_replace(' ', '', strtolower($repeat_fn)) . ','; } $this->self_repeat = $self_repeat; // Set these before any duplication begins... may be needed $this->element_selectors = $element_selectors; $this->ownerDocument = $source_element instanceof PHPFrontDom ? $source_element : $source_element->ownerDocument; if ($this->ownerDocument) { # 1. Attempt to populate nodeList // Default is to fill up nodeList with elements corresponding to items in $element_selectors - children of $source_element // But if $self_repeat is true, fill up nodeList with repeatitions of $source_element. if (!$this->self_repeat) { if (is_string($element_selectors[0])) { $source_element_node_path = $source_element instanceof PHPFrontDom ? '//' : $source_element->getNodePath(); # A. We populate chidren of element for ($i = 0; $i < count($element_selectors); $i++) { # a. This element has specified which named children to populate # We're working with named children // Sanitize... $element_selectors[$i] = str_replace(array('::before', '::after'), '', $element_selectors[$i]); // Query... $elements = $this->ownerDocument->getElementsBySelector($element_selectors[$i], $source_element_node_path); // Add the result as is... whether empty or not. Seek() will fetch this value for this selector. Parser will ofcourse test non-emptinesss $this->addToNodeList($elements); } } else { # b. This element does not specify named children. # So we populate all children except SPACES and COMMENTS $children = $source_element->childNodes; foreach ($children as $key => $node) { if (!($node instanceof DOMText || $node instanceof DOMComment)) { $this->addToNodeList(array($node)); } } # 2. IF the above didn't produce anything, that is, the provided element cannot produce a child, // duplicate it to get a child if (empty($this->nodeList) && !empty($source_element)) { $node = $this->ownerDocument->duplicateNode($source_element, 'sub_child'); $this->addToNodeList(array($node)); } } // In case number of items populated is smaller than expected number of calls, then we fill the list up $this->completeNodeList(); } else { // Repeat self // This element does not want to populate its children. $this->addToNodeList(array($source_element)); // In case number of items populated is smaller than expected number of calls, then we fill the list up $this->completeNodeList(); } } }
/** * @param \DOMNode $node * @return int */ protected function getDepth(\DOMNode $node) { $beef = array_filter(explode('/', $node->getNodePath())); return count($beef) - 1; }
/** * Merge the current node into the given container * * @param DOMNode $oContainer An element or a document * @param string $sSearchId The id to consider (could be blank) * @param bool $bMustExist Throw an exception if the node must already be found (and not marked as deleted!) */ public function MergeInto($oContainer, $sSearchId, $bMustExist) { $oTargetNode = $oContainer->_FindChildNode($this, $sSearchId); if ($oTargetNode) { if ($oTargetNode->getAttribute('_alteration') == 'removed') { if ($bMustExist) { throw new Exception("found mandatory node {$this->tagName}(id:{$sSearchId}) marked as deleted in " . $oContainer->getNodePath()); } // Beware: ImportNode(xxx, false) DOES NOT copy the node's attribute on *some* PHP versions (<5.2.17) // So use this workaround to import a node and its attributes on *any* PHP version $oTargetNode = $oContainer->ownerDocument->ImportNode($this->cloneNode(false), true); $oContainer->AddChildNode($oTargetNode); } } else { if ($bMustExist) { echo "Dumping parent node<br/>\n"; $oContainer->Dump(); throw new Exception("could not find {$this->tagName}(id:{$sSearchId}) in " . $oContainer->getNodePath()); } // Beware: ImportNode(xxx, false) DOES NOT copy the node's attribute on *some* PHP versions (<5.2.17) // So use this workaround to import a node and its attributes on *any* PHP version $oTargetNode = $oContainer->ownerDocument->ImportNode($this->cloneNode(false), true); $oContainer->AddChildNode($oTargetNode); } return $oTargetNode; }