如何从 foreach 中的 xml 中删除?
How can I delete from xml in foreach?
我有 xml 个文件。
<shop>
<categories>
<category id="132">kids</category>
<category id="62" parentId="133">women</category>
<category id="172" parentId="1">men</category>
</categories>
<materials>
<material id="1">one</material>
<material id="2">two</material>
<material id="3">soon</material>
</materials>
<offers>
<offer id="41850" available="true">
<price>3220</price>
<currencyId>EUR</currencyId>
<date>2015-02-05</date>
</offer>
<offer id="41850" available="true">
<price>3220</price>
<currencyId>EUR</currencyId>
<date>2015-02-05</date>
</offer>
<offer id="41850" available="true">
<price>3220</price>
<currencyId>EUR</currencyId>
<date>2015-02-05</date>
</offer>
<offer id="77777" available="true">
<price>3250</price>
<currencyId>EUR</currencyId>
<date>2015-02-05</date>
</offer>
<offer id="41340" available="true">
<price>3120</price>
<currencyId>EUR</currencyId>
<date>2015-02-05</date>
</offer>
我需要删除类别和资料。之后我需要删除所有不唯一的报价并将其写入新的 xml 文件。
我的问题。我无法删除非独特优惠。请帮我!谢谢。这是我的代码。
$url = 'test.xml';
$yml = simplexml_load_file($url);
unset($yml->shop->categories);
unset($yml->shop->materials);
$itemid = '0';
foreach ($yml->shop->offers->offer as $item){
$sravnit = $item['id'];
if("$sravnit" == "$itemid") {
echo "$sravnit eq $itemid delete<br>";
unset($yml->shop->offers->offer[$sravnit]);
continue;
else {echo "$sravnit not eq $itemid ";
$itemid = $sravnit;
echo "itemid to - $itemid <br>";
}
}
$yml->asXML('odd.xml');
此语法在多个方面都没有意义:
unset($yml->shop->offers->offer[$sravnit]);
<shop>
是您的根节点,由 $yml
.
表示
所以路径是$yml->offers->offer
你不能像这样select ID 为$sravnit
的<offer>
。错了。
相反,SimpleXml
将 select nth 节点,如下所示:
<drinks>
<drink id="2">beer</drink>
<drink id="5">wine</drink>
<drink id="0">water</drink>
</drinks>
echo $xml->drink[2];
是 water
,对不起。查一下:https://eval.in/464564
http://php.net/manual/en/simplexml.examples-basic.php 是推荐阅读。
使用 unset()
:请参阅此答案 Remove a child with a specific attribute, in SimpleXML for PHP 以深入了解如何组合 xpath()
和 unset()
进行删除SimpleXml
.
的特定节点
在您的情况下,您可能首先检查 <offer>
节点中的非唯一 ID 属性,然后在第二步中删除它们。
第 1 步:非唯一 ID 列表
用 xpath()
创建一个包含所有 id 值的数组,如下所示:
$ids = $yml->xpath("//offer/@id");
$ids
是SimpleXml
个元素的数组,用array_map()
转成整数值:
$ids = array_map("intval", $ids);
获取数组$ids
的非唯一值:
$ids = array_count_values($ids);
将return一个索引=id且值=count的数组:
array(3) {
[41850]=>int(3)
[77777]=>int(1)
[41340]=>int(1)
}
唯一id的值为1,所以让我们删除所有这些:
$ids = array_diff($ids, array(1));
现在你有一个包含所有非唯一 ID 的数组,让我们翻转索引和值:
$ids = array_flip($ids);
这是结果:
array(1) {
[3]=>int(41850)
}
总结:让我们把前面的所有步骤写成两行:
$ids = $yml->xpath("//offer/@id");
$ids = array_flip(array_diff(array_count_values(array_map("intval", $ids)), array(1)));
步骤 #2:删除 $ids
中具有 id
属性的所有 <offer>
:
我将使用 xpath()
到 select 节点,并使用 unset()
删除它:
foreach ($ids as $id) {
foreach ($xml->xpath("//offer[@id='$id']") as $item)
unset ($item[0]);
}
查看实际效果:https://eval.in/464608
我有 xml 个文件。
<shop>
<categories>
<category id="132">kids</category>
<category id="62" parentId="133">women</category>
<category id="172" parentId="1">men</category>
</categories>
<materials>
<material id="1">one</material>
<material id="2">two</material>
<material id="3">soon</material>
</materials>
<offers>
<offer id="41850" available="true">
<price>3220</price>
<currencyId>EUR</currencyId>
<date>2015-02-05</date>
</offer>
<offer id="41850" available="true">
<price>3220</price>
<currencyId>EUR</currencyId>
<date>2015-02-05</date>
</offer>
<offer id="41850" available="true">
<price>3220</price>
<currencyId>EUR</currencyId>
<date>2015-02-05</date>
</offer>
<offer id="77777" available="true">
<price>3250</price>
<currencyId>EUR</currencyId>
<date>2015-02-05</date>
</offer>
<offer id="41340" available="true">
<price>3120</price>
<currencyId>EUR</currencyId>
<date>2015-02-05</date>
</offer>
我需要删除类别和资料。之后我需要删除所有不唯一的报价并将其写入新的 xml 文件。
我的问题。我无法删除非独特优惠。请帮我!谢谢。这是我的代码。
$url = 'test.xml';
$yml = simplexml_load_file($url);
unset($yml->shop->categories);
unset($yml->shop->materials);
$itemid = '0';
foreach ($yml->shop->offers->offer as $item){
$sravnit = $item['id'];
if("$sravnit" == "$itemid") {
echo "$sravnit eq $itemid delete<br>";
unset($yml->shop->offers->offer[$sravnit]);
continue;
else {echo "$sravnit not eq $itemid ";
$itemid = $sravnit;
echo "itemid to - $itemid <br>";
}
}
$yml->asXML('odd.xml');
此语法在多个方面都没有意义:
unset($yml->shop->offers->offer[$sravnit]);
<shop>
是您的根节点,由$yml
.
表示 所以路径是$yml->offers->offer
你不能像这样select ID 为
$sravnit
的<offer>
。错了。
相反,SimpleXml
将 select nth 节点,如下所示:<drinks> <drink id="2">beer</drink> <drink id="5">wine</drink> <drink id="0">water</drink> </drinks>
echo $xml->drink[2];
是water
,对不起。查一下:https://eval.in/464564
http://php.net/manual/en/simplexml.examples-basic.php 是推荐阅读。使用
unset()
:请参阅此答案 Remove a child with a specific attribute, in SimpleXML for PHP 以深入了解如何组合xpath()
和unset()
进行删除SimpleXml
. 的特定节点
在您的情况下,您可能首先检查 <offer>
节点中的非唯一 ID 属性,然后在第二步中删除它们。
第 1 步:非唯一 ID 列表
用
xpath()
创建一个包含所有 id 值的数组,如下所示:$ids = $yml->xpath("//offer/@id");
$ids
是SimpleXml
个元素的数组,用array_map()
转成整数值:$ids = array_map("intval", $ids);
获取数组
$ids
的非唯一值:$ids = array_count_values($ids);
将return一个索引=id且值=count的数组:
array(3) { [41850]=>int(3) [77777]=>int(1) [41340]=>int(1) }
唯一id的值为1,所以让我们删除所有这些:
$ids = array_diff($ids, array(1));
现在你有一个包含所有非唯一 ID 的数组,让我们翻转索引和值:
$ids = array_flip($ids);
这是结果:
array(1) { [3]=>int(41850) }
总结:让我们把前面的所有步骤写成两行:
$ids = $yml->xpath("//offer/@id"); $ids = array_flip(array_diff(array_count_values(array_map("intval", $ids)), array(1)));
步骤 #2:删除 $ids
中具有 id
属性的所有 <offer>
:
我将使用 xpath()
到 select 节点,并使用 unset()
删除它:
foreach ($ids as $id) {
foreach ($xml->xpath("//offer[@id='$id']") as $item)
unset ($item[0]);
}
查看实际效果:https://eval.in/464608