Comment puis-je supprimer un noeud spécifique en utilisant sa valeur d'attribut dans PHP XML Dom?

ma question Est meilleure expression que: supprimer un enfant avec un attribut spécifique, en SimpleXML pour PHP

sauf que je n'utilise pas simpleXML.

je suis nouveau au XML pour PHP donc je ne fais peut-être pas de la meilleure façon

j'ai un xml créé en utilisant $dom->save($xml) pour chaque utilisateur individuel. (ne pas placer le tout dans un xml due à des raisons non divulguées)

il me donne que la déclaration xml <?xml version="1.0"?> (aucune idée de comment le faire à d'autres, mais ce n'est pas le point, espérons-le)

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

et je veux supprimer une catégorie qui a un attribut spécifique nommé id avec la classe DOM en php quand j'exécute une fonction activée à l'aide d'un bouton Supprimer.

voici le debug de la fonction im essayant de se rendre au travail. Puis-je savoir ce que je fais mal?

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

Eh bien, le ci-dessus m'imprime un tableau de [0] - >0 tout le temps quand je fente le retour en dehors de la fi. est-il un meilleur moyen? J'ai essayé d'utiliser getElementbyId, mais je ne sais pas comment faire.

je préférerais ne pas utiliser un attribut cependant si cela rendait les choses plus faciles.

1
demandé sur Community 2009-01-19 13:21:19

4 réponses

OK, essayons cet exemple complet d'utilisation:

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')), '</pre>';
4
répondu Gumbo 2009-01-19 16:10:51

donc vous voulez supprimer le noeud category avec un id spécifique ?

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

vous pouvez également utiliser XPath pour obtenir le noeud, par exemple:

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

Je ne l'ai pas testé mais ça devrait marcher.

1
répondu Gumbo 2009-01-19 10:53:33

pouvez-vous essayer avec cette version modifiée:

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

ça marche pour moi. Juste l'adapter à vos besoins. Ce n'est pas destiné à être utilisé tel quel, mais juste une preuve de concept. Vous devez également supprimer la déclaration xml de la chaîne de caractères.

0
répondu stunti 2009-01-19 15:07:30

au-dessus d'une fonction modifiée pour supprimer un e-mail à partir d'une liste de diffusion

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
répondu alex 2010-05-12 12:03:29