【问题标题】:How do I delete XML nodes in PHP based on the information inside of it?如何根据其中的信息删除 PHP 中的 XML 节点?
【发布时间】:2013-05-22 16:30:04
【问题描述】:

前言:有很多类似的问题,我已经翻遍了很多。没有什么能完全回答我需要做什么。

这是我的数据结构。 (明显简化)

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

我需要检查每张票的第一项,如果&lt;jewelry_metal&gt;标签为空,则删除整个&lt;ticket&gt;。在这一点上,我愿意接受任何建议。

【问题讨论】:

  • 使用 XML 解析器来解析您的数据。用你选择的语言把它读成一个大结构。操作结构中的数据。将修改后的数据写入新的 XML 文件。

标签: php xml dom xml-parsing simplexml


【解决方案1】:

您最好的选择是使用 XPath 和 DomDocument。试试这个:

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

输出将是:

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

希望这会有所帮助!

【讨论】:

  • 我很难接受 DOM 解析器是曾经某人的“最佳选择”...
  • 这是朝着正确方向迈出的一步,但我需要删除整个&lt;ticket&gt;,而不仅仅是&lt;item&gt;。这实际上是我被挂断的部分,哈哈。
【解决方案2】:

我建议您为此使用 Xpath 语言。让我们翻译一下:

我需要检查每张票的第一项,如果&lt;jewelry_metal&gt;标签为空,则删除整个&lt;ticket&gt;

进入xpath:

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

这将查询所有要删除的元素。在这个问题中解释了要在 PHP 中使用 simplexml 运行这样的 xpath 查询,然后删除元素:

确保您已启用错误报告,因为您提供的有问题的 XML 已完全损坏。以防万一你没有注意到。

【讨论】:

    猜你喜欢
    • 2013-02-11
    • 2014-11-21
    • 2013-12-02
    • 2022-01-19
    • 2016-11-23
    • 1970-01-01
    • 2013-10-21
    • 2014-04-05
    • 1970-01-01
    相关资源
    最近更新 更多