2013-10-27 96 views
0

我試圖通過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> 

有沒有辦法做到這一點?

+0

那麼,就克隆要複製的節點,改變你從中刪除的時間節點(我用'DOMDocument'&有點xpath'本的',但你可以創建和XSLT爲了這)。但是:您的原始結構似乎比您想要的輸出更可行。是否有一個特殊的原因需要輸出? – Wrikken

+0

@Wrikken是的,有一個原因。我需要將其轉換爲JSON。它使JSON代碼更加可行(對我而言)。 – Jorik

回答

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'); 
+0

謝謝你的回答。 output.xml文件只顯示一個人的第一個時間元素。我希望每個人都能得到一個時間元素,就像第二個例子中的結構一樣(參見上文)。 – Jorik

+0

我爲我的粗心大意道歉。我稍微改變了算法。我希望那是你需要的。 – Anchoret

+0

完美的作品!非常感謝你! – Jorik