xml öğeleri silmek?

4 Cevap php

I silmek istediğiniz bir xml belgedeki bazı unsurlar var. bu yüzden bu unsurların olmadan başka bir xml belgesi oluşturmak istiyorum.

Burada o anda nasıl göründüğünü bir örnek:

<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>

i alt kategori ve konu unsurları olmadan başka bir xml belgesi oluşturmak istiyorum.

böylece yeni biri bu gibi görünecektir:

<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>

ben bunu yapmak için SimpleXML / php veya XSLT kullanmalıyım? başka yolları var mı?

Bazı kod örnekleri ile harika olurdu ... teşekkürler!

4 Cevap

Bir yolu DOM, her düğümün üst kapmak ve kaldırmak için kullanabileceğiniz sonra kaldırmak istediğiniz düğümleri seçer XPath ifadesini tanımlamak için düğüm söyledi. SimpleXML bunu yapmak için kolay bir yol yoktur.

Karmaşık manipülasyonlar bu tür için, ben kullanmak 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();

(Ben sonsuza dek beri bu kullanarak oldum çünkü. SimpleXML daha iyi olup olmadığını gerçekten bilmiyorum sadece) PHP'nin DOMDocument sınıfını ve ilgili sınıfları kullanarak öneririm.

Sen aşağıdaki yapardın:

$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));
   }
}

Note that i just wrote that from the top of my hat, so please don't sue if it doesn't work, but it should be reasonably close.
Apart from that, in order to find the nodes to be deleted in a more elegant way, have a look at the PHPs DOMXPath object.

Burada kullandığım bazı yararlı fonksiyonlar

/* ***** 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);
    }
}

Bu örnek için çalışır, ancak gevşek bir top biraz fazla olabilir.

$doc = new DOMDocument();
$doc->loadXML($xml);
$xpath = new DOMXPath($doc);

foreach ($xpath->query('entities/entity/entities') as $elem) {
    $elem->parentNode->removeChild($elem);
}