11

我正在创建一个 Atom 提要,当我尝试在下面添加xmlns:i为属性时 -

$node->addAttribute("xmlns:i","http://www.w3.org/2001/XMLSchema-instance"); 

我得到了这个作为输出 -

i="http://www.w3.org/2001/XMLSchema-instance"

"xmlns:"部分被切断。我需要转义:-字符吗?或者他们是否有任何其他方式来添加这个命名空间?

4

3 回答 3

22

如果您想将命名空间/前缀中的属性添加i到 $node,请不要事先声明命名空间。只需使用 addAttribute() 的第三个参数为您在第一个参数中使用的前缀提供命名空间 uri。

$node = new SimpleXMLElement('<root></root>');
$node->addAttribute("i:somename", "somevalue", 'http://www.w3.org/2001/XMLSchema-instance'); 
echo $node->asXml();

印刷

<?xml version="1.0"?>
<root xmlns:i="http://www.w3.org/2001/XMLSchema-instance" i:somename="somevalue"/>

如果不需要属性本身,您可以使用 删除它unset(),留下命名空间声明。

unset($node->attributes('i', TRUE)['somename']);
于 2009-10-20T08:07:27.777 回答
20

如果您不想为根元素添加虚拟属性,可以通过为前缀添加xmlns属性来手动声明命名空间:i

<root xmlns:i="http://www.w3.org/2001/XMLSchema-instance">

为此,正如现有答案(Unable to add Attribute with Namespace Prefix using PHP Simplexml中所暗示的那样),您必须为新属性添加前缀xmlns:(因为xmlns:您的文档中未声明命名空间前缀)。并且由于xmlns:是该属性名称的一部分,因此您需要出现两次xmlns:

$uri = 'http://www.w3.org/2001/XMLSchema-instance';

$root = new SimpleXMLElement('<root/>');
$root->addAttribute( 'xmlns:xmlns:i', $uri );
                      ######

$child = $root->addChild('foo');
$child->addAttribute( 'xmlns:i:bar', 'baz');
                       ######

echo $root->asXml();

给出(手动格式化以提高可读性):

<?xml version="1.0"?>
<root xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <foo i:bar="baz"/>
</root>

所以这个xmlns:前缀似乎欺骗了它。请注意,如果您在设置该属性重新加载元素,则在添加子项时也可以使用命名空间 uri,这无需指定前缀:

$root = new SimpleXMLElement( $root->asXML() );

$child = $root->addChild('foo');
$child->addAttribute( 'i:bar', 'bazy', $uri );
                                       ####

echo $root->asXml();

给出(再次,手动格式化):

<?xml version="1.0"?>
<root xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
    <foo i:bar="baz"/>
    <foo i:bar="bazy"/>
</root>

第二个示例似乎更接近预期(或至少预期)的用途。

请注意,正确执行此操作的唯一方法是使用更完整(但不幸的是也更复杂和更冗长)的DOMDocument类。这在如何使用 DOM/PHP 声明 XML 命名空间前缀中进行了概述?.

于 2012-02-22T08:53:32.597 回答
4

我发现这是在寻找同样的东西,但没有一个答案真的对我有用。所以,我尝试了不同的路线。如果 SimpleXML 没有正确管理命名空间,请改用 DOM。

所以,这样的事情应该有效:

$s = new simplexmlelement('<root/>');
$d = dom_import_simplexml($s);
$d->setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns:i", "http://www.w3.org/2001/XMLSchema-instance");
$s->addChild("bar", "bazy", "http://www.w3.org/2001/XMLSchema-instance");
$f = $s->addChild("foo", "quux");
$f->addAttribute("i:corge", "grault", "http://www.w3.org/2001/XMLSchema-instance");

这将导致:

<?xml version="1.0"?>
<root xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
   <i:bar>bazy</i:bar>
   <foo i:corge="grault">quux</foo>
</root>
于 2014-04-11T20:01:34.677 回答