38 private $validationState;
83 private static $urnResolver;
89 private static $resolvedSchemaPaths = [];
107 array $idAttributes = [],
112 $this->validationState = $validationState;
113 $this->schema = $schemaFile;
114 $this->nodeMergingConfig =
new Dom\NodeMergingConfig(
new Dom\NodePathMatcher(), $idAttributes);
118 $this->rootNamespace = $this->dom->lookupNamespaceUri($this->dom->namespaceURI);
131 $validationErrors = libxml_get_errors();
132 if (count($validationErrors)) {
133 foreach ($validationErrors as $error) {
137 $errors[] =
'Unknown validation error';
167 protected function _mergeNode(\DOMElement $node, $parentPath)
176 if ($this->typeAttributeName &&
177 $node->hasAttribute($this->typeAttributeName) &&
178 $matchedNode->hasAttribute($this->typeAttributeName) &&
179 $node->getAttribute($this->typeAttributeName) !== $matchedNode->getAttribute($this->typeAttributeName)
182 $newNode = $this->dom->importNode($node,
true);
183 $parentMatchedNode->replaceChild($newNode, $matchedNode);
188 if (!$node->hasChildNodes()) {
194 if (!$matchedNode->hasChildNodes() || $this->
_isTextNode($matchedNode)) {
195 $matchedNode->nodeValue = $node->childNodes->item(0)->nodeValue;
199 foreach ($node->childNodes as $childNode) {
200 if ($childNode instanceof \DOMElement) {
208 $newNode = $this->dom->importNode($node,
true);
209 $parentMatchedNode->appendChild($newNode);
221 return $node->childNodes->length == 1 && $node->childNodes->item(0) instanceof \DOMText;
233 foreach ($mergeNode->attributes as
$attribute) {
247 $prefix = $this->rootNamespace ===
null ?
'' : self::ROOT_NAMESPACE_PREFIX .
':';
249 $idAttribute = $this->nodeMergingConfig->getIdAttribute(
$path);
250 if (is_array($idAttribute)) {
254 $constraints[] =
"@{$attribute}='{$value}'";
256 $path .=
'[' . implode(
' and ', $constraints) .
']';
257 }
elseif ($idAttribute && (
$value = $node->getAttribute($idAttribute))) {
258 $path .=
"[@{$idAttribute}='{$value}']";
273 $xPath = new \DOMXPath($this->dom);
274 if ($this->rootNamespace) {
275 $xPath->registerNamespace(self::ROOT_NAMESPACE_PREFIX, $this->rootNamespace);
277 $matchedNodes = $xPath->query($nodePath);
279 if ($matchedNodes->length > 1) {
280 throw new \Magento\Framework\Exception\LocalizedException(
282 "More than one node matching the query: %1, Xml is: %2",
283 [$nodePath, $this->dom->saveXML()]
286 }
elseif ($matchedNodes->length == 1) {
287 $node = $matchedNodes->item(0);
310 if (!self::$urnResolver) {
313 if (!isset(self::$resolvedSchemaPaths[
$schema])) {
314 self::$resolvedSchemaPaths[
$schema] = self::$urnResolver->getRealPath(
$schema);
318 libxml_use_internal_errors(
true);
319 libxml_set_external_entity_loader([self::$urnResolver,
'registerEntityLoader']);
328 libxml_use_internal_errors(
false);
332 libxml_set_external_entity_loader(
null);
333 libxml_use_internal_errors(
false);
345 private static function _renderErrorMessage(\LibXMLError $errorInfo,
$format)
348 foreach ($errorInfo as $field =>
$value) {
349 $placeholder =
'%' . $field .
'%';
353 if (strpos(
$result,
'%') !==
false) {
354 if (preg_match_all(
'/%.+%/',
$result, $matches)) {
356 foreach ($matches[0] as $placeholder) {
357 if (strpos(
$result, $placeholder) !==
false) {
358 $unsupported[] = $placeholder;
361 if (!empty($unsupported)) {
362 throw new \InvalidArgumentException(
363 "Error format '{$format}' contains unsupported placeholders: " . implode(
', ', $unsupported)
390 $dom = new \DOMDocument();
391 $useErrors = libxml_use_internal_errors(
true);
392 $res =
$dom->loadXML($xml);
394 $errors = self::getXmlErrors($this->errorFormat);
395 libxml_use_internal_errors($useErrors);
396 throw new \Magento\Framework\Config\Dom\ValidationException(implode(
"\n",
$errors));
398 libxml_use_internal_errors($useErrors);
399 if ($this->validationState->isValidationRequired() &&
$this->schema) {
402 throw new \Magento\Framework\Config\Dom\ValidationException(implode(
"\n",
$errors));
417 if ($this->validationState->isValidationRequired()) {
432 $this->schema = $schemaFile;
442 private function _getAttributeName(
$attribute)
449 return $attributeName;
validate($schemaFileName, &$errors=[])
_getNodePathByParent(\DOMElement $node, $parentPath)
elseif(isset( $params[ 'redirect_parent']))
static validateDomDocument(\DOMDocument $dom, $schema, $errorFormat=self::ERROR_FORMAT_DEFAULT)
const ROOT_NAMESPACE_PREFIX
__construct( $xml, \Magento\Framework\Config\ValidationStateInterface $validationState, array $idAttributes=[], $typeAttributeName=null, $schemaFile=null, $errorFormat=self::ERROR_FORMAT_DEFAULT)
_mergeNode(\DOMElement $node, $parentPath)
const ERROR_FORMAT_DEFAULT
_mergeAttributes($baseNode, $mergeNode)
_getMatchedNode($nodePath)
setSchemaFile($schemaFile)