Delete xml node && data in the case node the same data?

$xml = '<books>    
            <book>
                <qty>12</qty>
                <title>C++</title>
            </book>
            <book>
                <qty>21</qty>
                <title>PHP</title>
            </book>    
        </books>    
        <books>        
            <book>  
            <qty>21</qty>
            <title>JAVA</title>
            </book>    
        </books>';


$str = '<content>'.$xml.'</content>';

$doc = new DOMDOcument;
$doc->loadxml($str);

$xpath = new DOMXpath($doc);

$arr = array(
    array('12;C++', '21;PHP')
);

# Remove elements based on qty and title
foreach($arr as $items) {
    foreach($items as $item) {
        list($qty, $title) = explode(';', $item);
        foreach($xpath->query('/content/books/book[title="'.$title.'"][qty="'.$qty.'"]') as $book) {
            $book->parentNode->removeChild($book);
        }
    }
}

# Remove empty <books>
foreach($xpath->query('books[count(book)=0]') as $empty) {
    $empty->parentNode->removeChild($empty);
}
header('Content-type: text/xml');
echo $doc->savexml();

OUTPUT:

<content>
    <books>
        <book>
            <qty>21</qty>
            <title>JAVA</title>
        </book>
    </books>
</content>

But if the xml contain the same data like this:

$xml = '<books>    
            <book>
                <qty>12</qty>
                <title>C++</title>
            </book>
            <book>
                <qty>21</qty>
                <title>PHP</title>
            </book>    
        </books>    
        <books>        
            <book>  
                <qty>21</qty>
                <title>PHP</title> <!-- here the same data-->
            </book>    
        </books>';

it should get output something like this:

<content>
    <books>
        <book>
            <qty>21</qty>
            <title>PHP</title>
        </book>
    </books>
</content>

Why it delete all of my nodes ?and I got

<content>
</content>

Answers


If you want only the first match removed, just add break to the loop that searches for the elements:

# Remove elements based on qty and title
foreach($arr as $items) {
    foreach($items as $item) {
        list($qty, $title) = explode(';', $item);
        foreach($xpath->query('/content/books/book[title="'.$title.'"][qty="'.$qty.'"]') as $book) {
            $book->parentNode->removeChild($book);
            break; // <- Handle only the first match
        }
    }
}

Need Your Help

RhinoMocks AAA Syntax

rhino-mocks arrange-act-assert

I've spent a good part of the day trying to figure out why a simple RhinoMocks test doesn't return the value I'm setting in the return. I'm sure that I'm just missing something really simple but I ...

What's the most efficient way to render a template that changes based on primary key of a table (Django)

django django-views

I am creating a search page where users can search by parameters. The search parameters change based on the category they are searching in. There are approximately 100 categories and each has its own

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.