Разбор XML с пространством имен в RootElement в PHP

У меня есть следующий XML-файл с пространством имен:

<?xml version = "1.0" encoding = "utf-8"?>
<dc:languages xmlns:dc = "http://purl.org/dc/elements/1.1/">
    <dc:lang name = "C">
        <dc:appeared>1972</dc:appeared>
        <dc:creator>Dennis Ritchie</dc:creator>
    </dc:lang>
    <dc:lang name = "PHP">
        <dc:appeared>1995</dc:appeared>
        <dc:creator>Rasmus Lerdorf</dc:creator>
    </dc:lang>
    <dc:lang name = "Java">
        <dc:appeared>1995</dc:appeared>
        <dc:creator>James Gosling</dc:creator>
    </dc:lang>
</dc:languages>

Я хочу прочитать значение создателя, но мой код не работает.

$languages = simplexml_load_string($myXMLData);
$ns = $languages->getNamespaces(true);

$parent = $languages->$ns["lang"];

foreach($parent as $lang) {
    $dc = $lang->children($ns["dc"]);
    echo $dc->creator.'<br>';
}

Помогите, пожалуйста!

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
429
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы не должны использовать SimpleXMLElement::getNamespaces() для извлечения URI пространства имен из документа. Это определяющие значения, а не префиксы. Префиксы / псевдонимы являются необязательными для узлов XML-элементов и могут изменяться в любом узле элемента. Так что просто определите массив для всех пространств имен, которые вы используете.

SimpleXMLElement::children() действует как фильтр и возвращает SimpleXMLElement. Вы можете использовать синтаксис свойства для доступа к отфильтрованным дочерним элементам.

$languages = simplexml_load_string($xml);
$ns = [
  'dc' => 'http://purl.org/dc/elements/1.1/'
];

$parent = $languages->children($ns["dc"])->lang;    
foreach($parent as $lang) {
    $creator = $lang->children($ns["dc"])->creator;
    echo htmlspecialchars($creator).'<br>';
}

Выход:

Dennis Ritchie<br>Rasmus Lerdorf<br>James Gosling<br>

В DOM вы можете использовать Xpath (после регистрации пространств имен) для получения значений:

$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXpath($document);
$xpath->registerNamespace('d', 'http://purl.org/dc/elements/1.1/');

foreach($xpath->evaluate('/d:languages/d:lang') as $lang) {
    $creator = $xpath->evaluate('string(d:creator)', $lang);
    echo htmlspecialchars($creator), '<br>';
}

Я всегда с подозрением отношусь к своим излишне простым ответам.

bcperth 19.10.2018 16:05

Несмотря на действительно хороший ответ от ThW, похоже, это тоже работает ....

<?php


$xml= simplexml_load_string(
    '<?xml version = "1.0" encoding = "utf-8"?>
     <dc:languages version = "2" xmlns:dc = "http://purl.org/dc/elements/1.1/">
         <dc:lang name = "C">
             <dc:appeared>1972</dc:appeared>
             <dc:creator>Dennis Ritchie</dc:creator>
         </dc:lang>
         <dc:lang name = "PHP">
             <dc:appeared>1995</dc:appeared>
             <dc:creator>Rasmus Lerdorf</dc:creator>
         </dc:lang>
         <dc:lang name = "Java">
             <dc:appeared>1995</dc:appeared>
             <dc:creator>James Gosling</dc:creator>
         </dc:lang>
     </dc:languages>'
);


foreach($xml->xpath('//dc:lang') as $lang) {
    echo $lang->xpath('dc:creator')[0]."<br>";
}

и производит этот вывод из интерфейса командной строки.

Dennis Ritchie<br>Rasmus Lerdorf<br>James Gosling<br>

Однако мне пришлось изменить ваш XML, или simplexml_load_string () вернет ошибку.

<dc:languages xmlns:dc = "http://purl.org/dc/elements/1.1/">

к

<dc:languages version = "2" xmlns:dc = "http://purl.org/dc/elements/1.1/">

В LibXML есть некорректная функция, которая регистрирует определения пространств имен текущего контекста. Вы можете использовать Xpath с SimpleXML, но вы должны зарегистрировать пространства имен в каждом экземпляре SimpleXMLElement, на котором вы вызываете метод xpath().

ThW 21.10.2018 17:41

Другие вопросы по теме