[PHP]对SimpleXML进行转义

首先

由于PHP的SimpleXML的功能相对神秘,因此我总结了一下。

文本节点的转义

在使用SimpleXML将文本插入时,一般有大约三种方法。

$xml = new SimpleXMLElement('<root></root>');

$text = '"PHP&XML!"\(>_@)/';
/*1つめ*/
$item1 = $xml->addChild('item1');
$item1[0] = $text;
$this->assertEquals($text,$item1[0]);

/*2つめ*/
$text2 = $xml->addChild('item2')->{0} = $text;
$this->assertEquals($text,$xml->item2[0]);

/*3つめ*/
$item3 = $xml->addChild('item3',$text);
$this->assertEquals($text,$item3[0]);

其中的第三个无法通过断言。
如果在addChild的第二个参数中添加了文本,
奇怪的是,它不会自动转义和替换掉&符号。这很奇怪。

第二点是以一行代码创建元素并输入文本非常方便,但需要注意的是返回值自然不是SimpleXMLElement,而是文本。

使用$item[0]进行输入,使用$item[0]进行输出比较稳定。

特性转义

属性的输入有两种方式。

$xml = new SimpleXMLElement('<root></root>');

$text = '"PHP&XML!"\(>_@)/';

/*1つめ*/
$item1 = $xml->addChild('item1');
$item1->addAttribute('attr1',$text);
$this->assertEquals($text,$item1['attr1']);

/*2つめ*/
$item2 = $xml->addChild('item2');
$item2['attr2'] = $text;
$this->assertEquals($text,$item2['attr2']);

考虑到addChild的行为,addAttribute也可能会转义失败,但这里两者都会正确转义,这可能会让使用SimpleXML的人感到困惑。

XPath的转义

没有存在。
因为没有准备好函数,所以不能简单地使用正则表达式,也不至于到要死要活的地步。
SimpleXML的XPath是1.0版本,所以没有一个合适的定义形式来进行转义。

写下下面这段代码,最终会导致程序崩溃。

$target = current($xml->xpath('./haystack/book[title/text()="' . $needle. '"]'));

让我们使用循环逐一进行搜索。

$target = null;
foreach($xml->xpath('./haystack/book') as $book){
 if ($book->title[0] === $needle){
   $target = $book;
   break;
 }
}

结束

顺便提一下,可以通过unset来删除元素和属性,具体操作如下。

$target = $xml->item1;

/*属性の削除*/
unset($target['attr1']);

/*エレメントの削除*/
unset($target[0]);

考虑到$text的各个方面,可以说SimpleXML以数组的形式处理XML的感觉。

广告
将在 10 秒后关闭
bannerAds