Searches for all nodes with a style attribute, transforms the CSS found
to HTML attributes and adds those attributes to each node.

@param \DOMXPath $xPath

@return void
760755
private function mapAllInlineStylesToHtmlAttributes(\DOMXPath $xPath)
    {
        /** @var \DOMElement $node */
        foreach ($this->getAllNodesWithStyleAttribute($xPath) as $node) {
            $inlineStyleDeclarations = $this->parseCssDeclarationsBlock($node->getAttribute('style'));
            $this->mapCssToHtmlAttributes($inlineStyleDeclarations, $node);
        }
    }
329394
protected function getFormField($xpath)
    {
        $fieldNode = $this->getCrawlerNode($this->getFilteredCrawler($xpath));
        $fieldName = str_replace('[]', '', $fieldNode->getAttribute('name'));

        $formNode = $this->getFormNode($fieldNode);
        $formId = $this->getFormNodeId($formNode);

        if (!isset($this->forms[$formId])) {
            $this->forms[$formId] = new Form($formNode, $this->getCurrentUrl());
        }

        if (is_array($this->forms[$formId][$fieldName])) {
            return $this->forms[$formId][$fieldName][$this->getFieldPosition($fieldNode)];
        }

        return $this->forms[$formId][$fieldName];
    }
1361310
private function loadParam(\DOMXPath $xpath, \DOMNode $node)
    {
        $result = [
            'name' => $this->getValueFromXPath('@name', $xpath, $node),
            'type' => $this->getValueFromXPath('@type', $xpath, $node, 'string'),
            'meta' => $this->loadMeta($xpath, $node),
        ];

        switch ($result['type']) {
            case 'collection':
                $result['value'] = $this->loadParams('x:param', $xpath, $node);
                break;
            default:
                $result['value'] = $this->getValueFromXPath('@value', $xpath, $node);
                break;
        }

        return $result;
    }
738091
public void setXpath(String xpath) {

        if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(xpath)) {
            xpath = xpath.trim();
            if (xpath.startsWith("/")) {
                xpath = xpath.substring(1);
            }
            if (xpath.endsWith("/")) {
                xpath = xpath.substring(0, xpath.length() - 1);
            }
        }
        m_xpath = xpath;
    }
996333
protected static function removeInvalidAttributes(DOMDocument $dom)
	{
		$xpath = new DOMXPath($dom);
		foreach ($xpath->query('//@*') as $attribute)
		{
			if (!preg_match('(^(?:[-\\w]+:)?(?!\\d)[-\\w]+$)D', $attribute->nodeName))
			{
				$attribute->parentNode->removeAttributeNode($attribute);
			}
		}
	}
687664
public function getAttribute($xpath, $name) {
    $elements = $this->findElement($xpath, 1);
    return $this->browser->attribute($elements["page_id"], $elements["ids"][0], $name);
  }
1207164
public function render(\DOMDocument $domDocument)
    {
        $style3dXml = $domDocument->createElement("style3d");
        $this->checkId();
        if ($this->styleId) {
            $style3dXml->setAttribute("id", $this->styleId);
        }
        if ($this->model) {
            $style3dXml->setAttribute("model", $this->model);
        }
        if ($this->thickness) {
            $style3dXml->setAttribute("thickness", $this->thickness);
        }
        if ($this->color) {
            $style3dXml->setAttribute("color", $this->color);
        }
        if ($this->focusColor) {
            $style3dXml->setAttribute("fcolor", $this->focusColor);
        }
        if ($this->lightColor) {
            $style3dXml->setAttribute("lightcolor", $this->lightColor);
        }
        if ($this->focusLightColor) {
            $style3dXml->setAttribute("flightcolor", $this->focusLightColor);
        }
        if ($this->yOffset) {
            $style3dXml->setAttribute("yoffset", $this->yOffset);
        }
        if ($this->focusYOffset) {
            $style3dXml->setAttribute("fyoffset", $this->focusYOffset);
        }
        if ($this->zOffset) {
            $style3dXml->setAttribute("zoffset", $this->zOffset);
        }
        if ($this->focusZOffset) {
            $style3dXml->setAttribute("fzoffset", $this->focusZOffset);
        }
        return $style3dXml;
    }
1373112
protected function addStyleElementToDocument(\DOMDocument $document, $css)
    {
        $styleElement = $document->createElement('style', $css);
        $styleAttribute = $document->createAttribute('type');
        $styleAttribute->value = 'text/css';
        $styleElement->appendChild($styleAttribute);

        $bodyElement = $this->getBodyElement($document);
        $bodyElement->appendChild($styleElement);
    }
812561
private function getDefaultConfiguration(\DOMXPath $xpath)
    {
        $charFilters = $this->parseFilters($xpath, self::CHAR_FILTER_TYPE_ROOT_NODE, self::CHAR_FILTER_TYPE_NODE);
        $filters     = $this->parseFilters($xpath, self::FILTER_TYPE_ROOT_NODE, self::FILTER_TYPE_NODE);
        $analyzers   = $this->parseAnalyzers($xpath, array_keys($charFilters), array_keys($filters));

        $defaultConfiguration = [
            self::CHAR_FILTER_TYPE_NODE => $charFilters,
            self::FILTER_TYPE_NODE      => $filters,
            self::ANALYZER_TYPE_NODE    => $analyzers,
        ];

        return $defaultConfiguration;
    }
442267
protected function _deserializeDateTimeExtractionPaths(DOMXPath $xpath)
	{
		foreach ($this->_dateTimeExtractionPaths as $setter => $path) {
			$value = $xpath->evaluate($path);
			if ($value) {
				$this->$setter(new DateTime($value));
			}
		}
		return $this;
	}
386013
protected function _css_toxpath_selector($css_selector) {
		$xpath = $css_selector;

		// if there was passed a xpath expression
		if (strpos($xpath, 'xpath:') !== false) return substr($xpath, 6);

		// child elements
		$xpath = preg_replace('/([a-z0-9_-])\s+([a-z0-9_-])/', '$1//$2', $xpath);

		// direct child elements ( > )
		$xpath = preg_replace('/\s*>\s*/', '/', $xpath);

		// element with attribute
		$xpath = preg_replace('/\[([^\]]+)\]/', '[@$1]', $xpath);

		// element with starts-with selector
		$xpath = preg_replace('/\[@(.+)\^=(.+)\]/i', '[starts-with(@$1, $2)]', $xpath);

		// element with contains selector
		$xpath = preg_replace('/\[@(.+)\*=(.+)\]/i', '[contains(@$1, $2)]', $xpath);

		// element by id
		$xpath = preg_replace('/#([a-z0-9_-]+)/', '*[@id="$1"]', $xpath);

		// elements by class
		$xpath = preg_replace('/\.([a-z0-9_-]+)/', '*[contains(concat(" ", @class, " ")," $1 ")]', $xpath);

		// cleanup such elements div*
		$xpath = preg_replace('/([a-z0-9_-]+)\*/', '$1', $xpath);

		// first-child
		$xpath = preg_replace('/:first-child/', '[1]', $xpath);

		// nth-child
		$xpath = preg_replace('/:nth-child\((\d+)\)/', '[$1]', $xpath);

		// following elements ( + )
		$xpath = preg_replace('/\s*\+\s*/', '/following-sibling::*[1]/self::', $xpath);

		return '//' . $xpath;
	}
432116
protected function _cleanEmptyParents($dom, $parentXPath, $childXPath)
    {
        $xPath = new DomXPath($dom);
        $nodeList = $xPath->query($parentXPath);

        foreach ($nodeList as $node) {
            $id = $node->getAttribute('id');
            $childList = $xPath->query("{$parentXPath}[@id='$id']/$childXPath");
            if (!$childList->length) {
                $node->parentNode->removeChild($node);
            }
        }
    }
434794
public function loadDomDocument(\DOMDocument $domDocument)
    {
        $this->_dom = $domDocument;
        foreach ($this->_getNodesForCssSelector('[style]') as $node) {
            $node->setAttribute(
                'inlinestyle-original-style',
                $node->getAttribute('style')
            );
        }
    }
226645
protected function process()
    {
        $this->clearAllCaches();
        $this->purgeVisitedNodes();

        $xPath = new \DOMXPath($this->domDocument);
        $this->removeUnprocessableTags();
        $this->normalizeStyleAttributesOfAllNodes($xPath);

        // grab any existing style blocks from the html and append them to the existing CSS
        // (these blocks should be appended so as to have precedence over conflicting styles in the existing CSS)
        $allCss = $this->css;
        if ($this->isStyleBlocksParsingEnabled) {
            $allCss .= $this->getCssFromAllStyleNodes($xPath);
        }

        $excludedNodes = $this->getNodesToExclude($xPath);
        $cssRules = $this->parseCssRules($allCss);
        foreach ($cssRules['inlineable'] as $cssRule) {
            try {
                $nodesMatchingCssSelectors = $xPath->query($this->cssSelectorConverter->toXPath($cssRule['selector']));
            } catch (SyntaxErrorException $e) {
                if ($this->debug) {
                    throw $e;
                }
                continue;
            }

            /** @var \DOMElement $node */
            foreach ($nodesMatchingCssSelectors as $node) {
                if (\in_array($node, $excludedNodes, true)) {
                    continue;
                }
                $this->copyInlineableCssToStyleAttribute($node, $cssRule);
            }
        }

        if ($this->isInlineStyleAttributesParsingEnabled) {
            $this->fillStyleAttributesWithMergedStyles();
        }
        $this->postProcess($xPath);

        $this->removeImportantAnnotationFromAllInlineStyles($xPath);

        $this->copyUninlineableCssToStyleNode($xPath, $cssRules['uninlineable']);
    }
1086108
private function getAllLanguages(\DOMXPath $xpath)
    {
        $languages = [];

        foreach ($xpath->query('//*[@language]') as $currentNode) {
            $languages[] = $currentNode->getAttribute('language');
        }

        return array_unique($languages);
    }
140499
protected function loadStructureTags($path, $xpath)
    {
        $result = [];

        foreach ($xpath->query($path) as $node) {
            $tag = [
                'name' => null,
                'attributes' => [],
            ];

            foreach ($node->attributes as $key => $attr) {
                if (in_array($key, ['name'])) {
                    $tag[$key] = $attr->value;
                } else {
                    $tag['attributes'][$key] = $attr->value;
                }
            }

            if (!isset($tag['name'])) {
                // this should not happen because of the XSD validation
                throw new \InvalidArgumentException('Tag does not have a name in template definition');
            }

            $result[] = $tag;
        }

        return $result;
    }
638739
public function xpath($path)
    {
        $xpath = new \DOMXPath($this->dom);

        $list = $xpath->query($path);

        $return = [];
        foreach ($list as $node) {
            $return[] = $this->newElement($node);
        }

        return $return;
    }