使用PHP编辑XML结构

时间:2013-10-27 15:39:58

标签: php xml

我正在尝试通过PHP脚本转换XML文件。我有以下结构:

<?xml version="1.0"?>
<persons>

<person id="1">
      <periods>3</periods>
      <name id="John"/>
      <times>
        <time>
          <day id="1"/>
          <time>35:28</time >
          <length>8000</length>
        </time>
        <time>
          <day id="4"/>
          <time>8:28</time >
          <length>2000</length>
        </time>
        <time>
          <day id="5"/>
          <time>3:03</time >
          <length>1000</length>
        </time>
      </times>
    </person>

 <person id="2">
      <periods>3</periods>
      <name id="James"/>
      <times>
        <time>
          <day id="3"/>
          <time>45:20</time >
          <length>15000</length>
        </time>
        <time>
          <day id="5"/>
          <time>4:48</time >
          <length>1500</length>
        </time>
      </times>
    </person>
etc…
etc…
</persons>

每个人都有一个或多个时间元素。我想转换结构,所以每个人元素只有一个时间元素(如下面的结构)。

<?xml version="1.0"?>
<persons>
    <person id="1">
      <periods>3</periods>
      <name id="John"/>
      <times>
        <time>
          <day id="1"/>
          <time>35:28</time >
          <length>8000</length>
        </time>
      </times>
    </person>

    <person id="1">
      <periods>3</periods>
      <name id="John"/>
      <times>
        <time>
          <day id="4"/>
          <time>8:28</time >
          <length>2000</length>
        </time>
      </times>
    </person>

    <person id="1">
      <periods>3</periods>
      <name id="John"/>
      <times>
        <time>
          <day id="5"/>
          <time>3:03</time >
          <length>1000</length>
        </time>
      </times>
    </person>

<person id="2">
      <periods>2</periods>
      <name id="James"/>
      <times>
        <time>
          <day id="3"/>
          <time>45:20</time >
          <length>15000</length>
        </time>
      </times>
    </person>

<person id="2">
      <periods>2</periods>
      <name id="James"/>
      <times>
        <time>
          <day id="5"/>
          <time>4:48</time >
          <length>1500</length>
        </time>
      </times>
    </person>
</persons>

有办法做到这一点吗?

1 个答案:

答案 0 :(得分:0)

我真的非常懂英语,但我会尽力回答:)

我认为,执行此任务将适合SimpleXml和Dom扩展。 以下是执行所需转换的简单脚本。 input.xml是包含源文本的文件。 算法的结果将保存到output.xml文件中。

<?php
$simpleXml = new SimpleXMLElement(file_get_contents('input.xml'));
$personElements = $simpleXml->person;

$personForAppend = array();
$personsForRemove = array();

foreach ($personElements as $personElement) {
    $timeElements = $personElement->times->xpath("child::time");
    $numberOfTimeElements = count($timeElements);

    if ($numberOfTimeElements > 1) {
        $personDomElement = dom_import_simplexml($personElement);
        $backupTimeDomElementArray = array();

        foreach ($timeElements as $timeElement) {
            $timeDomElement = dom_import_simplexml($timeElement);
            $backupTimeDomElementArray[] = clone $timeDomElement;
            $timeDomElement->parentNode->removeChild(
                $timeDomElement
            );
        }

        while ($timeDomElement = array_shift($backupTimeDomElementArray)) {
            $copyPersonDomElement = clone $personDomElement;
            $copyPersonDomElement->getElementsByTagName('times')
                ->item(0)->appendChild($timeDomElement);
            $personForAppend[] = $copyPersonDomElement;
        }
        $personsForRemove[] = $personDomElement;
    }
}

foreach ($personForAppend as $personDomeNode) {
    $personDomElement->parentNode->appendChild($personDomeNode);
}

foreach ($personsForRemove as $personDomElement) {
    $personDomElement->parentNode->removeChild($personDomElement);
}
$simpleXml->saveXML('output.xml');