SimpleXML имеет объявление xmlns: xmlns = "" - нет способа удалить - PullRequest
4 голосов
/ 08 июля 2011

Настолько яростно, что едва могу говорить. Я собрал RSS-канал с SimpleXML и все же - он использует пространства имен, которые сейчас есть. Но он постоянно пытается объявить xmlns: xmlns = "" в корневом узле при выводе. Хотя я этого не делаю.

начинается с

$rssXML->addAttribute("version", '2.0');
$rssXML->addAttribute("xmlns:media", "http://search.yahoo.com/mrss/", '');
$rssXML->addAttribute("xmlns:dcterms", "http://purl.org/dc/terms/", '');

и после этого я делаю: -

header("Content-Type: application/rss+xml");

echo $syndicationXML->asXML();

Тем не менее он выводит: -

<?xml version="1.0"?>
<rss xmlns:xmlns="" version="2.0" xmlns:media="http://search.yahoo.com/mrss/" xmlns:dcterms="http://purl.org/dc/terms/"><channel>...

Я не понимаю всю эту декларацию пространства имен. Что происходит?

Ответы [ 3 ]

7 голосов
/ 08 июля 2011

Проблема с SimpleXML заключается в том, что функция addAttribute добавляет атрибут, а не пространство имен, и, хотя кажется, что он делает то, что вам нужно, он не предназначен для использования так, как вы его используете.

Он предназначен для добавления значения, являющегося частью определенного пространства имен (указанного в качестве третьего параметра), а не для добавления самого пространства имен.Причина, по которой вы в итоге получаете xmlns:xmlns, заключается в том, что SimpleXML обнаружил, что вы использовали пространство имен xmlns при указании имени xmlns:media, например, поэтому он создал пустое xmlns:xmlns.

Вот 2 решенияк вашей проблеме:

1.Укажите в пространствах имен в конструкторе.

$rssXML = new SimpleXMLElement('<rss xmlns:media="http://search.yahoo.com/mrss/" xmlns:dcterms="http://purl.org/dc/terms/" />');
$rssXML->addAttribute('version', '2.0');

2.Заменить xmlns:xmlns="", используя preg_replace

echo preg_replace('/xmlns:xmlns=""\s?/', '', $rssXML->asXML());
1 голос
/ 15 сентября 2016

SimpleXMLElement может только косвенно добавлять пространства имен.Поскольку вы можете добавлять только узлы элементов и атрибутов, а не объявления пространств имен, текстовые узлы или другие типы узлов, вы должны каким-то образом использовать SimpleXMLElement->addAttribute() или SimpleXMLElement->addChild().Последний будет только добавлять новые пространства имен для дочернего элемента, поэтому здесь он бесполезен.addAttribute() добавит пространство имен вместе с атрибутом к данному элементу, поэтому, если вы затем удалите атрибут, у вас останется пространство имен по вашему желанию.

Не существует очевидного метода удаленияатрибута, но использование unset, как показано в нескольких ответах на « Удаление дочернего элемента с определенным атрибутом, в SimpleXML для PHP », можно адаптировать к задаче, используя SimpleXMLElement->attributes(), чтобы получить ссылку на атрибут.

<?php
$rssXML = new SimpleXMLElement('<rss/>');
$rssXML->addAttribute("version", '2.0');
# add a dummy attribute to get the namespace
$rssXML->addAttribute("media:_", '', "http://search.yahoo.com/mrss/");
unset($rssXML->attributes('media', TRUE)[0]);
# and again
$rssXML->addAttribute("dcterms:_", '', "http://purl.org/dc/terms/");
unset($rssXML->attributes('dcterms', TRUE)[0]);

echo $rssXML->asXML(), "\n";

Результат:

<?xml version="1.0"?>
<rss xmlns:media="http://search.yahoo.com/mrss/" xmlns:dcterms="http://purl.org/dc/terms/" version="2.0"/>

Преимущество этого в том, что вы добавляете объявление пространства имен в качестве атрибута с подставленным поддельным пространством имен - оно обрабатываетсяв качестве пространства имен, а не атрибута, который в своем имени имеет нечто, похожее на префикс пространства имен.

var_export($rssXML->getDocNamespaces());

Результат:

array (
  'media' => 'http://search.yahoo.com/mrss/',
  'dcterms' => 'http://purl.org/dc/terms/',
)
1 голос
/ 02 мая 2013

Вы написали, что хотите это удалить.Лучший способ - не ставить его на первое место.

Это работает путем добавления префикса к xmlns: (в другой раз) - он каким-то образом включает специальный режим работы в simplexml - и не предоставление пустого URI пространства имен (в противном случае вы фактически запрашиваете его добавление):

$rssXML = new SimpleXMLElement('<rss/>');
$rssXML->addAttribute("version", '2.0');
$rssXML->addAttribute("xmlns:xmlns:media", "http://search.yahoo.com/mrss/");
$rssXML->addAttribute("xmlns:xmlns:dcterms", "http://purl.org/dc/terms/");
$rssXML->asXML('php://output');

Это создает следующий вывод (украшенный для вашего удовольствия от чтения):

<?xml version="1.0"?>
<rss version="2.0" 
     xmlns:media="http://search.yahoo.com/mrss/" 
     xmlns:dcterms="http://purl.org/dc/terms/"/>

This "cheat"изначально намекали на " Невозможно добавить атрибут с префиксом пространства имен с использованием PHP Simplexml ", но здесь его не было.

...