удалить элементы в XML? - PullRequest
1 голос
/ 23 марта 2010

У меня есть некоторые элементы в документе 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 ]

2 голосов
/ 23 марта 2010

Вот некоторые полезные функции, которые я использую

/* ***** 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 голосов
/ 23 марта 2010

Я бы предложил использовать класс 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 объект .

1 голос
/ 23 марта 2010

Это работает для вашего сэмпла, но это может быть слишком много для свободной пушки.

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

foreach ($xpath->query('entities/entity/entities') as $elem) {
    $elem->parentNode->removeChild($elem);
}
1 голос
/ 23 марта 2010

Одним из способов является определение выражения 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...