PHP Conference Japan 2024

SimpleXMLElement::addAttribute

(PHP 5 >= 5.1.3, PHP 7, PHP 8)

SimpleXMLElement::addAttribute 向 SimpleXML 元素添加属性

描述

public SimpleXMLElement::addAttribute(字符串 $qualifiedName, 字符串 $value, ?字符串 $namespace = null): void

向 SimpleXML 元素添加属性。

参数

qualifiedName

要添加的属性的名称。

value

属性的值。

namespace

如果指定,则为属性所属的命名空间。

返回值

不返回值。

示例

注意:

列出的示例可能包含 example.php,它指的是在 基本用法 指南的第一个示例中找到的 XML 字符串。

示例 #1 向 SimpleXML 元素添加属性和子元素

<?php

include 'example.php';

$sxe = new SimpleXMLElement($xmlstr);
$sxe->addAttribute('type', 'documentary');

$movie = $sxe->addChild('movie');
$movie->addChild('title', 'PHP2: More Parser Stories');
$movie->addChild('plot', 'This is all about the people who make it work.');

$characters = $movie->addChild('characters');
$character = $characters->addChild('character');
$character->addChild('name', 'Mr. Parser');
$character->addChild('actor', 'John Doe');

$rating = $movie->addChild('rating', '5');
$rating->addAttribute('type', 'stars');

echo
$sxe->asXML();

?>

以上示例将输出类似以下内容

<?xml version="1.0" standalone="yes"?>
<movies type="documentary">
 <movie>
  <title>PHP: Behind the Parser</title>
  <characters>
   <character>
    <name>Ms. Coder</name>
    <actor>Onlivia Actora</actor>
   </character>
   <character>
    <name>Mr. Coder</name>
    <actor>El Act&#xD3;r</actor>
   </character>
  </characters>
  <plot>
   So, this language. It's like, a programming language. Or is it a
   scripting language? All is revealed in this thrilling horror spoof
   of a documentary.
  </plot>
  <great-lines>
   <line>PHP solves all my web problems</line>
  </great-lines>
  <rating type="thumbs">7</rating>
  <rating type="stars">5</rating>
 </movie>
 <movie>
  <title>PHP2: More Parser Stories</title>
  <plot>This is all about the people who make it work.</plot>
  <characters>
   <character>
    <name>Mr. Parser</name>
    <actor>John Doe</actor>
   </character>
  </characters>
  <rating type="stars">5</rating>
 </movie>
</movies>

参见

添加注释

用户贡献的注释 7 条注释

4
Patanjali
8 年前
您不能使用此方法更新现有属性的值。

相反,获取 SimpleXMLElement 的 DOM 版本并使用 setAttribute,如下所示:

$XML = '<element a="aa">Text</element>';
$snode = new simple_xml_element($XML);

$dnode = dom_import_simplexml($snode);
$dnode->setAttribute('a', 'bb');

节点的 XML 结果为
<element a="bb">Text</element>
3
booleer at yahoo dot it
13 年前
如果属性已存在,则 addAttribute 不会执行任何操作。

示例
<?php
$xml_string
= <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<root>
<item id="foo">
<root>
XML;

$xml = simplexml_load_string($xml_string);
$xml->item->addAttribute('id', 'bar');
echo
$xml->asXML();
?>

以上示例将输出
<?xml version="1.0" encoding="UTF-8"?>
<root>
<item id="foo">
<root>
2
caffeinatedbits
1 年前
刚刚发现另一个宝石。需要删除属性?这也很简单!

<?php

$xml
= <<<EOF
<?xml version="1.0" encoding="utf-8" ?>
<Animals>
<Dog breed="chihuahua"/>
</Animals>
EOF;

$animals = new SimpleXMLElement($xml);

echo
$animals->Dog->asXML();
// <Dog breed="chihuahua"/>

unset($animals->Dog['breed']);

echo
$animals->Dog->asXML();
// <Dog/>

?>
2
caffeinatedbits
1 年前
我需要一种更新属性的方法,但我找不到任何记录的方法来执行此操作。

经过多次实验,我发现了一些有效的方法——答案非常简单,我花了 8 次尝试才弄明白 :-)

给定以下示例

<?php

$xml
= <<<EOF
<?xml version="1.0" encoding="utf-8" ?>
<Animals>
<Dog/>
</Animals>
EOF;

$animals = new SimpleXMLElement($xml);

echo
$animals->Dog->asXML();
// <Dog/>

?>

测试 #6 - 也许直接修改 attributes() 迭代器(像数组一样)会暗中调用 __set() 魔术方法?

总结:是的

<?php

...

$animals->Dog->addAttribute('breed', "chihuahua");

echo
$animals->Dog->asXML();
// <Dog breed="chihuahua">

$dogAttrs = $animals->Dog->attributes();
// object(SimpleXMLElement)#4 (1) {
// ["@attributes"]=>
// array(1) {
// ["breed"]=>
// string(9) "chihuahua"
// }
// }

$dogAttrs['breed'] = "poodle";
// 可行!

echo $animals->Dog->asXML();
// <Dog breed="poodle">

?>

测试 #7 - 也许我根本不需要调用 attributes()?

总结:当然不需要!

<?php

...

$animals->Dog->addAttribute('breed', "chihuahua");

echo
$animals->Dog->asXML();
// <Dog breed="chihuahua">

$animals->Dog['breed'] = "poodle";
// 可行!

echo $animals->Dog->asXML();
// <Dog breed="poodle">

?>

测试 #8 - 也许我一开始就不需要调用 addAttribute()?

总结:不,我可以完全跳过它!

<?php

...

$animals->Dog['breed'] = "chihuahua";
// 可行!

echo $animals->Dog->asXML();
// <Dog breed="chihuahua">

$animals->Dog['breed'] = "poodle";
// 可行!

echo $animals->Dog->asXML();
// <Dog breed="poodle">

?>

仅供参考:我还提交了另一份单独的说明,其中列出了哪些方法无效,以防您(像我一样)感到好奇并想尝试其他方法。
1
p.servus
13 年前
如果您需要命名空间,则必须将命名空间的前缀 + 属性名称(“prefix:name”)作为第一个参数,并将 URI 作为第三个参数。(我不知道为什么?!)

示例代码
<?php
$xml
= new SimpleXMLElement("<packagedElement></packagedElement>");
$xml->addAttribute("xmi:type", "uml:Class", "http://schema.omg.org/spec/XMI/2.1");
echo
$xml->asXml();
?>

输出
<packagedElement xmlns:xmi="http://schema.omg.org/spec/XMI/2.1" xmi:type="uml:Class"></packagedElement>
0
caffeinatedbits
1 年前
我需要一种更新属性的方法,但我找不到任何记录的方法来执行此操作。

总结:这不仅是可能的,而且出奇地简单。请参阅我提交的其他说明以了解哪些方法实际上有效(抱歉,由于 4095 个字符的限制,我无法将所有内容都放在一个说明中)。

经过多次实验,我发现了一些无效的方法;希望这能为您节省我花费的时间和精力。

给定以下示例

<?php

$xml
= <<<EOF
<?xml version="1.0" encoding="utf-8" ?>
<Animals>
<Dog/>
</Animals>
EOF;

$animals = new SimpleXMLElement($xml);

echo
$animals->Dog->asXML();
// <Dog/>

?>

测试 #1 - 尝试两次调用 addAttribute()

总结:PHP 警告:SimpleXMLElement::addAttribute(): 属性已存在

<?php

...

$animals->Dog->addAttribute('breed', "chihuahua");

echo
$animals->Dog->asXML();
// <Dog breed="chihuahua"/>

$animals->Dog->addAttribute('breed', "poodle");
// PHP 警告:SimpleXMLElement::addAttribute(): 属性已存在

echo $animals->Dog->asXML();
// <Dog breed="chihuahua"/>

?>

测试 #2 - 尝试通过引用迭代 attributes()(迭代器)

总结:无法通过引用使用 foreach 迭代迭代器

<?php

...

$animals->Dog->addAttribute('breed', "chihuahua");

echo
$animals->Dog->asXML();
// <Dog breed="chihuahua">

try {
foreach (
$animals->Dog->attributes() as $attr => &$value) {
if (
"breed" === $attr) {
$value = "poodle";
}
}
} catch (
Throwable $e) {
echo
$e->getMessage();
// 无法通过引用使用 foreach 迭代迭代器
}

echo
$animals->Dog->asXML();
// <Dog breed="chihuahua">

?>

测试 #3 - 尝试重新解析子元素,然后在重新解析的元素上调用 addAttribute(),如我在此处找到的一则说明中所建议的那样

总结:PHP 警告:SimpleXMLElement::addAttribute(): 属性已存在

<?php

...

$animals->Dog->addAttribute('breed', "chihuahua");

echo
$animals->Dog->asXML();
// <Dog breed="chihuahua">

$animals->Dog = new SimpleXMLElement($animals->asXML());

$animals->Dog->addAttribute('breed', "poodle");
// PHP 警告:SimpleXMLElement::addAttribute(): 属性已存在

echo $animals->Dog->asXML();
// <Dog breed="chihuahua">

?>

测试 #4 - 尝试修改 @attributes 数组元素

总结:PHP 注意:对 SimpleXMLElement 的重载元素进行间接修改无效



<?php

...

$animals->Dog->addAttribute('breed', "chihuahua");

echo
$animals->Dog->asXML();
// <Dog breed="chihuahua">

$dogAttrs = $animals->Dog->attributes();
// object(SimpleXMLElement)#4 (1) {
// ["@attributes"]=>
// array(1) {
// ["breed"]=>
// string(9) "chihuahua"
// }
// }

$dogAttrs['@attributes']['breed'] = "poodle";
// PHP Notice: Indirect modification of overloaded element of SimpleXMLElement has no effect

echo $animals->Dog->asXML();
// <Dog breed="chihuahua">

?>

测试 #5 - 将 attributes() 转换为数组并设置 'breed' 元素的值

简而言之:不会更新原始对象中的值

<?php

...

$animals->Dog->addAttribute('breed', "chihuahua");

echo
$animals->Dog->asXML();
// <Dog breed="chihuahua">

$dogAttrs = (array) $animals->Dog->attributes();
// array(1) {
// ["@attributes"]=>
// array(1) {
// ["breed"]=>
// string(9) "chihuahua"
// }
// }

$dogAttrs['@attributes']['breed'] = "poodle";

echo
$animals->Dog->asXML();
// <Dog breed="chihuahua">

?>
0
sarlak
13 年前
您可以通过以下方式访问节点子节点及其名称

<?php
$root
= new SimpleXMLElement($filePath);
echo
$root->nodeName->attributes;

// 它递归工作,所以这也将起作用
echo $root->nodeName->subNodeName->attributes();
?>

但是,如果您想向子节点添加属性,则**必须**使用 children() 方法来访问和修改它,否则它将修改父节点的属性。

<?php
// 添加子节点
$element->nodeName->addChild('subNodeName', "whatever you want");

// 获取父节点子节点中的位置
$lastNodePos = $element->nodeName->count()-1;

// 获取父节点的子节点
$nodeChildrens = $element->nodeName->children();

// 向最后一个创建的节点添加属性
$nodeChildrens[$lastNodePos]->addAttribute('attributeName', "The attribute value);
?>
To Top