[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的感觉。