2017-08-29 45 views
1

我有下面的XML數據:順序輸出XML數據按日期

<schedule> 
    <event> 
    <date>2017-08-25</date> 
    <time>16:00</time> 
    </event> 
    <event> 
    <date>2017-08-25</date> 
    <time>20:00</time> 
    </event> 
    <event> 
    <date>2017-08-26</date> 
    <time>16:00</time> 
    </event> 
    <event> 
    <date>2017-08-26</date> 
    <time>20:00</time> 
    </event> 
    </event> 
    <event> 
    <date>2017-08-27</date> 
    <time>20:00</time> 
    </event> 
</schedule> 

要輸出的數據我用下面的循環:

<?php $xml = simplexml_load_file('events.xml'); ?> 
<?php foreach ($xml->event as $event) { ?> 
<dl> 
    <dt> 
     <?php echo $event->date; ?> 
    </dt> 
    <dd> 
     <?php echo $event->time; ?> 
    </dd> 
</dl> 
<?php } ?> 

結果是:

<dl> 
    <dt>2017-08-25</dt> 
    <dd>16:00</dd> 
</dl> 
<dl> 
    <dt>2017-08-25</dt> 
    <dd>20:00</dd> 
</dl> 
<dl> 
    <dt>2017-08-26</dt> 
    <dd>16:00</dd> 
</dl> 

但知道我想訂購按日期時間,得到這個輸出:

<dl> 
    <dt>2017-08-25</dt> 
    <dd>16:00</dd> 
    <dd>20:00</dd> 
</dl> 

<dl> 
    <dt>2017-08-26</dt> 
    <dd>16:00</dd> 
    <dd>20:00</dd> 
</dl> 

是否有修改循環,得到這個結果的呢?我會非常感謝任何幫助!

+1

看到這裏https://stackoverflow.com/questions/15204305/re-order-xml-results-based-on-xml-data – clearshot66

回答

1

考慮XSLT,設計來轉換XML文件中的特殊用途的語言,因爲你真正需要的是一個XSLT 1.0方法叫Muenchian Grouping,你組使用文檔鍵和檢索或操縱所有相應值的節點。

PHP可以使用其php-xsl擴展名(確保在.ini文件中啓用)運行XSLT 1.0腳本。採用這種方法,不需要foreach循環或if邏輯。

XSLT腳本(另存爲的.xsl文件,可以像任何XML處理專門的.xml文件)

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:output version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" /> 
<xsl:strip-space elements="*"/> 

<xsl:key name="eventid" match="event" use="date" /> 

    <xsl:template match="/schedule"> 
    <root> 
     <xsl:apply-templates select="event"/> 
    </root> 
    </xsl:template> 

    <xsl:template match="event"> 
    <dl>  
     <xsl:for-each select=".[generate-id() = generate-id(key('eventid', date)[1])]"> 
      <dt><xsl:value-of select="date"/></dt> 
      <xsl:for-each select="key('eventid', date)"> 
       <dd><xsl:value-of select="time"/></dd> 
      </xsl:for-each> 
     </xsl:for-each> 
    </dl>  
    </xsl:template> 

</xsl:transform> 

PHP(參照上面的.xsl文件)

// LOAD XML AND XSL 
$xml = new DOMDocument(); 
$xml->load('Input.xml');  // OR $xml->loadXML($xmlstring); 

$xsl = new DOMDocument; 
$xsl->load('XSLTScript.xsl'); // OR $xsl->loadXML($xslstring); 

// INITIALIZE TRANSFORMER 
$proc = new XSLTProcessor; 
$proc->importStyleSheet($xsl); 

// RUN TRANSFORMATION 
$newXML = $proc->transformToXML($xml); 

// ECHO STRING OUTPUT 
echo $newXML; 

// SAVE OUTPUT TO FILE 
file_put_contents('Output.xml', $newXML); 

輸出online transform

<root> 
    <dl> 
     <dt>2017-08-25</dt> 
     <dd>16:00</dd> 
     <dd>20:00</dd> 
    </dl> 
    <dl/> 
    <dl> 
     <dt>2017-08-26</dt> 
     <dd>16:00</dd> 
     <dd>20:00</dd> 
    </dl> 
    <dl/> 
    <dl> 
     <dt>2017-08-27</dt> 
     <dd>20:00</dd> 
    </dl> 
</root> 
+0

謝謝您的實現的詳細步驟!我喜歡使用XSLT的方式。可惜我忘了提及,我沒有修改XML文件的影響。該文件基於外部服務器上的API密鑰。 – Filip

+0

您並未修改原始XML,而是將原始文件轉換爲新文件並保存。如果你的輸出只是爲了屏幕,'echo $ newXML;'應該這樣做。 – Parfait