Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/293.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在PHP中重构XML_Php - Fatal编程技术网

在PHP中重构XML

在PHP中重构XML,php,Php,我收到了一个具有以下结构的XML文件: <items> <item> <images> <image>A</image> <image>B</image> <image>C</image> </images> . . . </item> </items> A. B C

我收到了一个具有以下结构的XML文件:

<items>
  <item>
    <images>
      <image>A</image>
      <image>B</image>
      <image>C</image>
    </images>
    .
    .
    .
  </item>
</items>

A.
B
C
.
.
.
但是,my Shop的导入功能需要以下格式:

<items>
  <item>
    <images>
      <image>A</image>
      <image1>B</image>
      <image2>C</image>
    </images>
    .
    .
    .
  </item>
</items>

A.
B
C
.
.
.
起初,我想我可以用Java简单地实现这一点,因为逐行阅读和重组文档非常容易,但我很想拥有它,这样我就可以访问url了,这是为我完成的

以下是我采取的方法:

<?php
$xml = simplexml_load_file('data.xml');


// Loop over items in original xml
for($i = 0; $i < count($xml->item); $i++)
{
    $images;
    if( ($c = count($xml->item[$i]->images->image)) > 1)
    {
        $images = $xml->item[$i]->images;

        // Remove entry
        unset($xml->item[$i]->images);

        $xml->item[$i]->addChild('images');

        for($y = 0; $y < count($images->image); $y++)
        {
            if($y == 0)
            {
                $xx = $xml->item[$i]->images->addChild('image', $images->image[$y]);

            }else {
                $xml->item[$i]->images->addChild('image' . $y, $images->image[$y]);
            }
        }

        var_dump($images);
    }
}

$xml->asXML('POTO.xml');
项目)$(i++)
{
$images;
如果($c=count($xml->item[$i]->images->image))>1)
{
$images=$xml->item[$i]->images;
//删除条目
取消设置($xml->item[$i]->images);
$xml->item[$i]->addChild('images');
对于($y=0;$yimage);$y++)
{
如果($y==0)
{
$xx=$xml->item[$i]->images->addChild('image',$images->image[$y]);
}否则{
$xml->item[$i]->images->addChild('image'.$y,$images->image[$y]);
}
}
var_dump($images);
}
}
$xml->asXML('POTO.xml');
我面临的困境是,没有一个孩子被添加到图像中。有人告诉我需要重新构造整个文档,但是如果我在删除images节点后立即执行
var_dump
操作,这会有点愚蠢。但是,当我将images节点添加回item节点时,节点及其子节点都会被删除,并且
var_dump
节点显示节点作为子节点添加到item节点,但是当我尝试将图像添加到图像中,但没有添加任何内容


我真的需要重新构造整个文档吗?因为在Java中这样做似乎更简单。或者我遗漏了什么。

好的,我认为这里的关键问题是,将图像分配给
$images
并不像您预期的那样工作。虽然这样的原语赋值会生成一个副本,但赋值对象会生成对同一对象的引用(类似于使用低级语言时使用的指针)。他们这样做是因为一个对象可能比一个原语大,而不必要的复制只是浪费

但是,在本例中,结果是,当您从主SimpleXML对象取消设置图像时,您也在破坏$images中的实例。幸运的是,有一个解决办法。您可以克隆对象,而不是分配对象。看

我在这里修改了您的示例代码,它似乎有效:

编辑:稍微清理了我的代码并将其包括在内:

<?php
//$xml = simplexml_load_file('data.xml');
$xml = simplexml_load_string('<items>
  <item>
    <images>
      <image>A</image>
      <image>B</image>
      <image>C</image>
    </images>
  </item>
</items>');

// Loop over items in original xml
foreach ($xml->item as $item) {
    if (count($item->images->image) > 1) {
        // Clone entry
        $images = clone $item->images;

        // Remove entry and replace with empty
        unset($item->images);
        $item->addChild('images');

        for ($i = 0; $i < count($images->image); $i++) {
            $num = ($i > 0) ? $i : '';
            $item->images->addChild('image'.$num, $images->image[$i]);
        }
    }
}

//$xml->asXML('POTO.xml');
echo $xml->asXML();
项目作为$item){
如果(计数($item->images->image)>1){
//克隆条目
$images=克隆$item->images;
//删除条目并替换为空
取消设置($item->images);
$item->addChild('images');
对于($i=0;$iimage);$i++){
$num=($i>0)?$i:“”;
$item->images->addChild('image'.$num,$images->image[$i]);
}
}
}
//$xml->asXML('POTO.xml');
echo$xml->asXML();
看起来这在版本5.2.1()之前是不起作用的,但实际上这要追溯到很久以前。Rasmus不希望任何人运行低于5.4(),我倾向于同意


作为记录,这种仅复制引用的行为并不是PHP的怪癖。这是一种常见的做法。进一步阅读:

2美分:调查。
count($xml->item)
count($images->image)
的值是多少?你的循环体被执行了吗?@GeorgeCummins计数语法在我看来也很有趣,但似乎是有效的。看起来PHP5.3带来了对
SimpleXMLElement::count()
对象方法的支持,但在此之前,使用基本
count()
实际上是标准的。谁知道呢?裁判: