我想从每个size="id"
元素中完全删除<door>
属性。
<?xml version="1.0" encoding="UTF-8"?>
<doors>
<door id="1" entry="3249" size="30"/>
<door id="1041" entry="6523" size="3094"/>
-- and 1000 more....
</doors>
PHP代码:
$xml = new SimpleXMLElement('http://mysite/doors.xml', NULL, TRUE);
$ids_to_delete = array( 1, 1506 );
foreach ($ids_to_delete as $id) {
$result = $xml->xpath( "//door[@size='$id']" );
foreach ( $result as $node ) {
$dom = dom_import_simplexml($node);
$dom->parentNode->removeChild($dom);
}
}
$xml->saveXml();
我没有错误,但它没有删除size属性。为什么呢?
答案 0 :(得分:1)
您可以使用DOMXPath在DOMDocument中完成整个查询,而不是在SimpleXML和DOM之间切换:
$dom = new DOMDocument;
$dom->load('my_xml_file.xml');
# initialise an XPath object to act on the $dom object
$xp = new DOMXPath( $dom );
# run the query
foreach ($xp->query( "//door[@size]" ) as $door) {
# remove the attribute
$door->removeAttribute('size');
}
print $dom->saveXML();
您提供的输入的输出:
<?xml version="1.0" encoding="UTF-8"?>
<doors>
<door id="1" entry="3249"/>
<door id="1041" entry="6523"/>
</doors>
如果您只想删除列表中ID的size
属性,则应使用以下代码:
foreach ($ids_to_delete as $id) {
# searches for elements with a matching ID and a size attribute
foreach ($xp->query("//door[@id='$id' and @size]") as $door) {
$door->removeAttribute('size');
}
}
您的代码无法正常工作:
看起来你的XPath错了,因为你的数组被调用$ids_to_delete
而你的XPATH正在寻找size元素等于$ids_to_delete
的值的门元素;
您正在将节点转换为DOMDocument对象($dom = dom_import_simplexml($node);
)以进行删除,但我认为您以某种方式打印的$xml->saveXml();
是一个SimpleXML对象;
您需要删除元素属性; removeChild
删除整个元素。
答案 1 :(得分:0)
我没有错误,但它没有删除size属性。为什么呢?
有多种原因导致它不删除size属性。首先出现在我脑海中的是属性不是子节点。使用删除子项的方法不适合删除属性。
每个元素节点都有一组关联的属性节点;元素是每个属性节点的父节点;但是,属性节点不是其父元素的子元素。
来自: Attribute Nodes - XML Path Language (XPath),由我大胆。
但是,这里没有看到错误,因为您拥有的$result
是一个空数组。您只是不选择要使用xpath删除任何要删除的节点(既不是元素也不是属性)。那是因为你找不到这样的元素:
//door[@size='1']
您正在搜索size属性中的id:No match。
这就是为什么你没有错误并且它不删除任何大小属性的原因:1。)你不删除属性,2。)你不查询任何元素来删除属性。
您可以通过使用Xpath查询选择它们来删除属性节点,然后取消设置SimpleXMLElement self-reference:
// all size attributes of all doors
$result = $xml->xpath("//door/@size");
foreach ($result as $node) {
unset($node[0]);
}
在此示例中,所有属性节点都由Xpath表达式查询,这些表达式是门元素的大小属性(这是您在问题中要求的),然后从XML中删除它们。
//door/@size
现在这里有完整的例子:
<?php
/**
* @link https://eval.in/215817
*/
$buffer = <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<doors>
<door id="1" entry="3249" size="30"/>
<door id="1041" entry="6523" size="3094"/>
-- and 1000 more....
</doors>
XML;
$xml = new SimpleXMLElement($buffer);
// all size attributes of all doors
$result = $xml->xpath("//door/@size");
foreach ($result as $node) {
unset($node[0]);
}
$xml->saveXml("php://output");
输出(Online Demo):
<?xml version="1.0" encoding="UTF-8"?>
<doors>
<door id="1" entry="3249"/>
<door id="1041" entry="6523"/>
-- and 1000 more....
</doors>