XML использует два пространства имен http://www.sitemaps.org/schemas/sitemap/0.9
без псевдонима и http://www.w3.org/1999/xhtml
с псевдонимом xhtml
.Чтобы читать XML с пространствами имен, вы должны использовать *NS
варианты методов DOM.
$urls = $urlsxml->getElementsByTagNameNS(
'http://www.sitemaps.org/schemas/sitemap/0.9', 'url'
);
$urls[$i]->getElementsByTagNameNS('http://www.w3.org/1999/xhtml', 'link');
Первый аргумент - это URI пространства имен, второй аргумент - локальное имя (имя узла с префиксом).В этом случае было бы неплохо использовать константу / переменную для URI пространства имен.
Более удобным вариантом является Xpath.Он позволяет использовать пути и условия местоположения для извлечения узлов.
$document = new DOMDocument;
$document->loadXML($xml);
// create an xpath instance for the document
$xpath = new DOMXpath($document);
// register the namespaces for your own prefixes
$xpath->registerNameSpace('s', 'http://www.sitemaps.org/schemas/sitemap/0.9');
$xpath->registerNameSpace('x', 'http://www.w3.org/1999/xhtml');
// iterate all sitemap url elements
foreach ($xpath->evaluate('//s:url') as $url) {
$data = [
// get the sitemap loc child element as a string
'loc' => $xpath->evaluate('string(s:loc)', $url),
// get the href attribute of the xhtml link element (with language condition)
'fr-ca' => $xpath->evaluate('string(x:link[@hreflang="fr-ca"]/@href)', $url),
];
var_dump($data);
}
Вывод:
array(2) {
["loc"]=>
string(58) "https://www.example.com/ca/en/cat/categories/series/07660/"
["fr-ca"]=>
string(58) "https://www.example.com/ca/fr/cat/categories/series/07660/"
}
array(2) {
["loc"]=>
string(58) "https://www.example.com/ca/en/cat/categories/series/07683/"
["fr-ca"]=>
string(58) "https://www.example.com/ca/fr/cat/categories/series/07683/"
}
string()
в Xpath преобразует первый узел в списке в строку.Это позволяет вам избежать явного доступа к свойствам объекта узла.Например, $xpath->evaluate('s:loc', $url)->item(0)->textContent;
можно записать как $xpath->evaluate('string(s:loc)', $url);
.В отличие от доступа к свойству, приведение Xpath не завершится с ошибкой, если не существует соответствующего узла.Он вернет пустую строку.