simpleXML虽然很容易用。但是需要知道XML的结构,否则操作起来是很麻烦的,甚至无法达到目的,毕竟API就那么几个,很局限。而相对来说,DOM操作的API就很多,大多数操作都能胜任。
simpleXML存在的问题:
比如xml结构有两个title
<msg>
<titles>
<title>3344</title>
<title>3344</title>
</titles>
</msg>
通过以下代码可以访问到2个title节点的值。但是这必须知道xml的结构。而且要替换节点的值,xpath是做不到的。是复制而不是引用。
$xml = simplexml_load_file("test.xml");
//echo count($xml->author->children());
$s = "title";
$num = count($xml->msg->$s);
$titles =$xml->msg->$s;
//$xml->msg->children();
$xpath = & $xml->xpath("//title");
foreach ($xml->msg->title as $child)
{
var_dump($child);
echo "Child node: " . $child;
$child = "sss";
}
$xml->asXML("test.xml");
如果通过遍历节点和属性来更改节点和属性的值,处理两个相同节点的时候,只能获取第一个节点的simplexmlElement对象,即使通过xpath拿到第二个也更改不了,因为是复制的。
例如:
1
$b = "title";
$node->$b[1] = "ccc";
2、
$node->$title[1] = "ccc";
$num = count($node-> $sub);
以上两个写法,第一个获取到的是空的simpleXMLELEMNT,它会新生成一个t的节点,内容是ccc。而第二个写法会找到第2个节点名称是title的节点并将它的内容改为ccc。
第一种完全偏离了我的想法。但没有其它办法达到第二种的效果。因此,我放弃了用simpleXML来解析XML。
-----------------------------
//遍历节点
function iterateNode($node) {
if (count($node->children()) == 0) {
echo "dfd";
} else {
foreach ($node->children() as $child) {
$sub = $child->getName(); //子节点名称
$child = replaceStr($child); //更改值
$subs = $node-> $sub;
if (count($subs) > 1) { //如果存在多个相同的子节点,则只会更改第一个节点的属性。因此要遍历更改
foreach ($subs as $i) {
iterateAttr($i); //更改属性
}
} else {
iterateAttr($node-> $sub); //更改属性
}
if (count($node->children()) == 0) {
@ $node-> $sub = replaceStr($sub); //会有warning提示。$node->$sub是数组类型。
} else {
$num = count($node-> $sub);
if ($num > 1) { //如果存在多个相同的子节点,则只会遍历第一个节点。
//$node->rectangle[1] 和 $node->$sub[1] 虽然$sub等于rectangle,但是这两者是不同的类型,
//第一个返回的是节点的值,而第二个返回的是一个空的simpleXML对象 SimpleXMLElement。
//可以通过xpath查询出节点的值,但是不能通过给xpath赋值改变节点的值。
for($i=0;$i<$num;$i++){
}
} else {
if(count($node->$sub->children()) == 0){
@ $node->$sub = replaceStr($node->$sub); //会有warning提示。$node->$sub是数组类型。
}else{
iterateNode($node-> $sub); //遍历子节点
}
}
}
}
}
}
//遍历属性 更改属性
function iterateAttr($node) {
foreach ($node->attributes() as $attr => $val) {
$newval = replaceStr($val);
$node["$attr"] = $newval; //更改XML文件内容
}
}
simpleXML存在的问题:
比如xml结构有两个title
<msg>
<titles>
<title>3344</title>
<title>3344</title>
</titles>
</msg>
通过以下代码可以访问到2个title节点的值。但是这必须知道xml的结构。而且要替换节点的值,xpath是做不到的。是复制而不是引用。
$xml = simplexml_load_file("test.xml");
//echo count($xml->author->children());
$s = "title";
$num = count($xml->msg->$s);
$titles =$xml->msg->$s;
//$xml->msg->children();
$xpath = & $xml->xpath("//title");
foreach ($xml->msg->title as $child)
{
var_dump($child);
echo "Child node: " . $child;
$child = "sss";
}
$xml->asXML("test.xml");
如果通过遍历节点和属性来更改节点和属性的值,处理两个相同节点的时候,只能获取第一个节点的simplexmlElement对象,即使通过xpath拿到第二个也更改不了,因为是复制的。
例如:
1
$b = "title";
$node->$b[1] = "ccc";
2、
$node->$title[1] = "ccc";
$num = count($node-> $sub);
以上两个写法,第一个获取到的是空的simpleXMLELEMNT,它会新生成一个t的节点,内容是ccc。而第二个写法会找到第2个节点名称是title的节点并将它的内容改为ccc。
第一种完全偏离了我的想法。但没有其它办法达到第二种的效果。因此,我放弃了用simpleXML来解析XML。
-----------------------------
//遍历节点
function iterateNode($node) {
if (count($node->children()) == 0) {
echo "dfd";
} else {
foreach ($node->children() as $child) {
$sub = $child->getName(); //子节点名称
$child = replaceStr($child); //更改值
$subs = $node-> $sub;
if (count($subs) > 1) { //如果存在多个相同的子节点,则只会更改第一个节点的属性。因此要遍历更改
foreach ($subs as $i) {
iterateAttr($i); //更改属性
}
} else {
iterateAttr($node-> $sub); //更改属性
}
if (count($node->children()) == 0) {
@ $node-> $sub = replaceStr($sub); //会有warning提示。$node->$sub是数组类型。
} else {
$num = count($node-> $sub);
if ($num > 1) { //如果存在多个相同的子节点,则只会遍历第一个节点。
//$node->rectangle[1] 和 $node->$sub[1] 虽然$sub等于rectangle,但是这两者是不同的类型,
//第一个返回的是节点的值,而第二个返回的是一个空的simpleXML对象 SimpleXMLElement。
//可以通过xpath查询出节点的值,但是不能通过给xpath赋值改变节点的值。
for($i=0;$i<$num;$i++){
}
} else {
if(count($node->$sub->children()) == 0){
@ $node->$sub = replaceStr($node->$sub); //会有warning提示。$node->$sub是数组类型。
}else{
iterateNode($node-> $sub); //遍历子节点
}
}
}
}
}
}
//遍历属性 更改属性
function iterateAttr($node) {
foreach ($node->attributes() as $attr => $val) {
$newval = replaceStr($val);
$node["$attr"] = $newval; //更改XML文件内容
}
}