Как удалить определенный узел, используя его значение атрибута в PHP XML Dom? - PullRequest
1 голос
/ 19 января 2009

Мой вопрос - лучшая фраза: Удалить дочерний элемент с определенным атрибутом в SimpleXML для PHP

за исключением того, что я не использую simpleXML.

Я новичок в XML для PHP, поэтому, возможно, у меня не все получается

У меня есть xml, созданный с использованием $ dom-> save ($ xml) для каждого отдельного пользователя. (не размещать все в одном xml по нераскрытым причинам)

Это дает мне эту декларацию xml <?xml version="1.0"?> (понятия не имею, как это сделать другим, но, надеюсь, дело не в этом)

<?xml version="1.0"?>
<details>
 <person>name</person>
 <data1>some data</data1>
 <data2>some data</data2>
 <data3>some data</data3>
 <category id="0">
  <categoryName>Cat 1</categoryName>
  <categorydata1>some data</categorydata1>
 </category>
 <category id="1">
  <categoryName>Cat 2</categoryName>
  <categorydata1>some data</categorydata1>
  <categorydata2>some data</categorydata2>
  <categorydata3>some data</categorydata3>
  <categorydata4>some data</categorydata4>
 </category>
</details>

И я хочу удалить категорию, имеющую определенный атрибут с именем id, с классом DOM в php, когда я запускаю функцию, активированную с помощью кнопки удаления.

Ниже приведена отладка функции, которую я пытаюсь заставить работать. Могу ли я знать, что я делаю не так?

function CatRemove($myXML){
        $xmlDoc = new DOMDocument();
        $xmlDoc->load( $myXML );
        $categoryArray = array();

        $main = $xmlDoc->getElementsByTagName( "details" )->item(0);

        $mainElement = $xmlDoc->getElementsByTagName( "details" );
        foreach($mainElement as $details){
            $currentCategory = $details->getElementsByTagName( "category" );
            foreach($currentCategory as $category){
                $categoryID = $category->getAttribute('id');
                array_push($categoryArray, $categoryID);
                if($categoryID == $_POST['categorytoremoveValue']) {
                    return $categoryArray;
                }
            }
        }


        $xmlDoc->save( $myXML );
    }

Что ж, вышеприведенный выводит мне массив [0] -> 0 все время, когда я вставляю возврат за пределы if. Есть ли способ лучше? Я также пытался использовать getElementbyId, но я не знаю, как это сделать.

Я бы предпочел не использовать атрибут, хотя, если это облегчило бы ситуацию.

Ответы [ 4 ]

4 голосов
/ 19 января 2009

Хорошо, давайте попробуем этот полный пример использования:

<code>function CatRemove($myXML, $id) {
    $xmlDoc = new DOMDocument();
    $xmlDoc->load($myXML);
    $xpath = new DOMXpath($xmlDoc);
    $nodeList = $xpath->query('//category[@id="'.(int)$id.'"]');
    if ($nodeList->length) {
        $node = $nodeList->item(0);
        $node->parentNode->removeChild($node);
    }
    $xmlDoc->save($myXML);
}

// test data
$xml = <<<XML
<?xml version="1.0"?>
<details>
 <person>name</person>
 <data1>some data</data1>
 <data2>some data</data2>
 <data3>some data</data3>
 <category id="0">
  <categoryName>Cat 1</categoryName>
  <categorydata1>some data</categorydata1>
 </category>
 <category id="1">
  <categoryName>Cat 2</categoryName>
  <categorydata1>some data</categorydata1>
  <categorydata2>some data</categorydata2>
  <categorydata3>some data</categorydata3>
  <categorydata4>some data</categorydata4>
 </category>
</details>
XML;
// write test data into file
file_put_contents('untitled.xml', $xml);
// remove category node with the id=1
CatRemove('untitled.xml', 1);
// dump file content
echo '<pre>', htmlspecialchars(file_get_contents('untitled.xml')), '
';
1 голос
/ 19 января 2009

То есть вы хотите удалить узел category с определенным id?

$node = $xmlDoc->getElementById("12345");
if ($node) {
    $node->parentNode->removeChild($node);
}

Вы также можете использовать XPath для получения узла, например:

$xpath = new DOMXpath($xmlDoc);
$nodeList = $xpath->query('//category[@id="12345"]');
if ($nodeList->length) {
    $node = $nodeList->item(0);
    $node->parentNode->removeChild($node);
}

Я не проверял его, но он должен работать.

0 голосов
/ 12 мая 2010

вышеупомянутая функция изменена для удаления электронного письма из списка рассылки

function CatRemove($myXML, $id) {
    $xmlDoc = new DOMDocument();
    $xmlDoc->load($myXML);
    $xpath = new DOMXpath($xmlDoc);
    $nodeList = $xpath->query('//subscriber[@email="'.$id.'"]');
    if ($nodeList->length) {
        $node = $nodeList->item(0);
        $node->parentNode->removeChild($node);
    }
    $xmlDoc->save($myXML);
}
$xml = 'list.xml';
$to = $_POST['email'];//user already submitted they email using a form 
CatRemove($xml,$to);
0 голосов
/ 19 января 2009

Можете ли вы попробовать с этой модифицированной версией:

function CatRemove($myXML, $id){
    $doc = new DOMDocument();
    $doc->loadXML($myXML);
    $xpath = new DOMXpath($doc);
    $nodeList = $xpath->query("//category[@id='$id']");
    foreach ($nodeList as $element) {
        $element->parentNode->removeChild($element);
    }

    echo htmlentities($doc->saveXML());
}

Это работает для меня. Просто адаптируйте его под свои нужды. Он не предназначен для использования как есть, а просто для подтверждения концепции. Вы также должны удалить объявление xml из строки.

...