我想要删除的xml文档中有一些元素。所以我想创建另一个没有这些元素的xml文档。
以下是目前的样子:
<entity id="1000070">
<name>apple</name>
<type>category</type>
<entities>
<entity id="7002870">
<name>mac</name>
<type>category</type>
<entities>
<entity id="7002907">
<name>leopard</name>
<type>sub-category</type>
<entities>
<entity id="7024080">
<name>safari</name>
<type>subject</type>
</entity>
<entity id="7024701">
<name>finder</name>
<type>subject</type>
</entity>
</entities>
</entity>
</entities>
</entity>
<entity id="7024080">
<name>iphone</name>
<type>category</type>
<entities>
<entity id="7024080">
<name>3g</name>
<type>sub-category</type>
</entity>
<entity id="7024701">
<name>3gs</name>
<type>sub-category</type>
</entity>
</entities>
</entity>
<entity id="7024080">
<name>ipad</name>
<type>category</type>
</entity>
</entities>
</entity>
我想创建另一个没有子类别和主题元素的xml文档。
所以新的将如下所示:
<entity id="1000070">
<name>apple</name>
<type>category</type>
<entities>
<entity id="7002870">
<name>mac</name>
<type>category</type>
</entity>
<entity id="7024080">
<name>iphone</name>
<type>category</type>
</entity>
<entity id="7024080">
<name>ipad</name>
<type>category</type>
</entity>
</entities>
</entity>
我应该使用simplexml / php或xslt来做到这一点吗?还有其他方法吗?
一些代码示例会很棒...谢谢!
答案 0 :(得分:2)
我建议使用PHP的DOMDocument类和相关类(如果只是因为我一直在使用它。不知道simplexml是否更好)。
您将执行以下操作:
$doc = new DOMDocument();
$doc->load($xml);
$rootNode = $doc->documentElement;
$entitiesNode = $rootNode->getElementsByTagName('entities')->item(0);
$entityNodes = $entitiesNode->getElementsByTagName('entity');
for($i = 0; $i < $entityNodes->length; $i++)
{
$entityNode = $entityNodes->item($i);
$subEntitiesNode = $entityNode->getElementsByTagName('entities');
if($subEntitiesNode->length)
{
$subEntitiesNode->removeChild($subEntitiesNode->item(0));
}
}
请注意,我刚从帽子顶部写下来,所以如果它不起作用请不要起诉,但它应该合理地接近。
除此之外,为了以更优雅的方式找到要删除的节点,请查看PHP DOMXPath object。
答案 1 :(得分:2)
这里有一些我用过的有用功能
/* ***** XML MANIPULATION FUNCTIONS ********* */
/**
Adds a new element in a XML list.
Add $xnew after $x in $docm.
*/
function XMLadd(DOMDocument $docm, DOMNode $x=null, DOMNode $newx=null, $mode=''){
if($x!=null && $newx!= null){
if($mode === "a_") {
if($x->nextSibling) {
$x->parentNode->insertBefore( $docm->importNode($newx, true), $x->nextSibling);
} else {
$x->parentNode->appendChild( $docm->importNode($newx, true));
}
} else {
$x->parentNode->insertBefore( $docm->importNode($newx, true), $x);
}
}
}
/**
Removes an element from a XML list.
Remove $x, $x must be DOMNode in a DOMDocument
*/
function XMLremove(DOMNode $x=null) {
if($x!=null) {
//remove item
$x->parentNode->removeChild( $x );
}
}
/**
Replace an element in a XML List.
Parameters: $x(DOMNode) will be replaced by $newx(DOMNode) in $docm (DOMDocument)
*/
function XMLreplace(DOMDocument $docm, DOMNode $x=null, DOMNode $newx=null) {
if($x!=null && $newx!= null) {
//replace = add + remove
//add new element
XMLadd($docm, $x, $newx);
//remove item
XMLremove($x);
}
}
答案 2 :(得分:1)
一种方法是定义XPath表达式,选择要删除的节点,然后使用DOM抓取每个节点的父节点并删除所述节点。 SimpleXML没有简单的方法。
对于那种复杂的操作,我使用SimpleDOM。
include 'SimpleDOM.php';
$entity = simpledom_load_file('/path/to/your/file.xml');
// either delete all "subject" and "sub-category"
$entity->deleteNodes('//entity[type="subject" or type="sub-category"]');
// or remove everything but "category"
$entity->deleteNodes('//entity[not(type="category")]');
// remove empty <entities/>
$entity->deleteNodes('//entities[count(child::*) = 0]');
echo $entity->asXML();
答案 3 :(得分:1)
这适用于您的样品,但它可能有点太松散的大炮。
$doc = new DOMDocument();
$doc->loadXML($xml);
$xpath = new DOMXPath($doc);
foreach ($xpath->query('entities/entity/entities') as $elem) {
$elem->parentNode->removeChild($elem);
}