删除xml中的元素?

时间:2010-03-23 12:10:13

标签: php xml

我想要删除的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来做到这一点吗?还有其他方法吗?

一些代码示例

会很棒...谢谢!

4 个答案:

答案 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);
}