令人气愤,我几乎无法说话。我已经使用SimpleXML组装了一个RSS提要 - 但它正在使用名称空间,现在就是这样。但是,当输出时,它会不断尝试在根节点中声明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>...
我不明白所有这个名称空间声明。发生了什么事?
答案 0 :(得分:7)
SimpleXML的问题在于它的addAttribute
函数添加了一个属性,而不是一个命名空间,虽然它看起来像你想要的那样,但它并不意味着以你使用它的方式使用。
这意味着添加一个特定命名空间(指定为第三个参数)的值,而不是添加命名空间本身。您最终使用xmlns:xmlns
的原因是因为SimpleXML发现您在指定名称xmlns
时使用了xmlns:media
命名空间,因此它创建了一个空xmlns:xmlns
。
以下是您的问题的两种解决方案:
<强> 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 :(得分:1)
您写道,您要删除它。最好的方法是不要把它放在第一位。
这通过前缀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/"/>
这个“作弊”最初是在"Unable to add Attribute with Namespace Prefix using PHP Simplexml"中暗示的,但在这里不见了。
答案 2 :(得分:1)
SimpleXMLElement
只能间接添加名称空间。由于您只能添加元素和属性节点,而不能添加名称空间声明,文本节点或其他节点类型,因此您必须以某种方式使用SimpleXMLElement->addAttribute()
或SimpleXMLElement->addChild()
。后者只会为孩子添加新的命名空间,所以在这里没用。 addAttribute()
会将命名空间和属性添加到给定元素中,因此,如果您删除该属性,则根据需要留下命名空间。
没有一种明显的删除属性的方法,但使用unset
如#34; Remove a child with a specific attribute, in SimpleXML for PHP&#34;的几个答案所示。可以使用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/',
)