Charles Zink
Charles Zink

Reputation: 3642

How do I delete XML nodes in PHP based on the information inside of it?

Preface: There are many questions similar to this that I've scoured through profusely. Nothing can quite answer what I need to do.

Here is my data structure. (obviously simplified)

<Upload>
    <tickets>
        <ticket>
            <ticket_number>123</ticket_number>
            <clerk>001</clerk>
            <property>
                <item>
                    <item_number>1</item>
                    <jewelry_metal>GOLD</jewelry_metal>
                </item>
                <item>
                    <item_number>2</item>
                    <jewelry_metal>SILVER</jewelry_metal>
                </item>
            </property>
        </ticket>
        <ticket>
            <ticket_number>456</ticket_number>
            <clerk>001</clerk>
            <property>
                <item>
                    <item_number>1</item>
                    <jewelry_metal></jewelry_metal>
                </item>
            </property>
        </ticket>
    <tickets>
<Upload>

I need to check the first item in each ticket, and if the <jewelry_metal> tag is empty, delete the entire <ticket>. I'm open to any suggestions at this point.

Upvotes: 0

Views: 144

Answers (2)

hakre
hakre

Reputation: 197832

I would suggest you use the Xpath language for that. Lets translate:

I need to check the first item in each ticket, and if the <jewelry_metal> tag is empty, delete the entire <ticket>

into xpath:

//ticket[.//item[1]/jewelry_metal = ""]

That will query all elements to delete. To run such an xpath query in PHP with simplexml and then delete the elements is explained in this question:

Ensure you've got error reporting enabled because your XML you've provided in question is totally broken. Just in case you didn't notice.

Upvotes: 0

Ardy Dedase
Ardy Dedase

Reputation: 1088

Your best bet here would be to use XPath and DomDocument. Try this:

<?php
$xmlstr = <<<XML
<?xml version='1.0'?>
<Upload>
    <tickets>
        <ticket>
            <ticket_number>123</ticket_number>
            <clerk>001</clerk>
            <property>
                <item>
                    <item_number>1</item_number>
                    <jewelry_metal>GOLD</jewelry_metal>
                </item>
                <item>
                    <item_number>2</item_number>
                    <jewelry_metal>SILVER</jewelry_metal>
                </item>
            </property>
        </ticket>
        <ticket>
            <ticket_number>456</ticket_number>
            <clerk>001</clerk>
            <property>
                <item>
                    <item_number>1</item_number>
                    <jewelry_metal></jewelry_metal>
                </item>
            </property>
        </ticket>
    </tickets>
</Upload>
XML;

$doc = new DOMDocument();
$doc->loadxml($xmlstr);

$xpath = new DOMXpath($doc);

foreach($xpath->query('//tickets/ticket/property/item[1]') as $key => $item) {
    if (empty($item->getElementsByTagName('jewelry_metal')->item(0)->nodeValue)) {
        $item->parentNode->removeChild($item);  
    }
}

echo $doc->saveXML();

The output will be:

<?xml version="1.0"?>
<Upload>
    <tickets>
        <ticket>
            <ticket_number>123</ticket_number>
            <clerk>001</clerk>
            <property>
                <item>
                    <item_number>1</item_number>
                    <jewelry_metal>GOLD</jewelry_metal>
                </item>
                <item>
                    <item_number>2</item_number>
                    <jewelry_metal>SILVER</jewelry_metal>
                </item>
            </property>
        </ticket>
        <ticket>
            <ticket_number>456</ticket_number>
            <clerk>001</clerk>
            <property>

            </property>
        </ticket>
    </tickets>
</Upload>

Hope this helps!

Upvotes: 1

Related Questions