PHP SimpleXML 删除重复项

PHP SimpleXML remove duplicates

我正在使用 php 简单 xml 从 xml 文件获取数据。我通过在时间节点中拆分时间戳来获取每次放映电影的时间和日期。每个循环都会显示每个日期以及每次,但如果在同一天显示不止一次,我希望日期只显示一次。

我想创建一个数组然后删除重复项,但这就​​是我遇到的问题,我一直在为每个时间创建一个单独的数组 loop.You 可以在底部看到我想要的输出像。谢谢...文件

<Event xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Attributes>
    <EventAttribute>
        <Name>Event Type</Name>
        <Value>Cinema</Value>
    </EventAttribute>
    <EventAttribute>
        <Name>Venue</Name>
        <Value>Building 1</Value>
    </EventAttribute>
</Attributes>
<Description />
<Duration>0</Duration>
<FirstInstance>2019-08-02T13:30:00</FirstInstance>
<Id>220002</Id>
<ImageUrl />
<LastInstance>2019-08-08T19:00:00</LastInstance>
<Name>Spider-Man: Far From Home (12a)</Name>
<OnSaleOnWeb>true</OnSaleOnWeb>
<ThumbnailUrl />
<Times>
    <EventTime>
        <Attributes>
            <EventAttribute>
                <Name>Venue</Name>
                <Value> Building 1</Value>
            </EventAttribute>
            <EventAttribute>
                <Name>Special Performance</Name>
                <Value />
            </EventAttribute>
        </Attributes>
        <Capacity>509</Capacity>
        <EventInstanceId>376802</EventInstanceId>
        <OnSaleOnWeb>true</OnSaleOnWeb>
        <SeatsAvailable>345</SeatsAvailable>
        <SeatsLocked>164</SeatsLocked>
        <SeatsReserved>0</SeatsReserved>
        <SeatsSelected>0</SeatsSelected>
        <SeatsSold>0</SeatsSold>
        <Time>2019-08-02T13:30:00</Time>
        <WebInstanceId i:nil="true" />
    </EventTime>
    <EventTime>
        <Attributes>
            <EventAttribute>
                <Name>Venue</Name>
                <Value> Building 1</Value>
            </EventAttribute>
            <EventAttribute>
                <Name>Special Performance</Name>
                <Value />
            </EventAttribute>
        </Attributes>
        <Capacity>509</Capacity>
        <EventInstanceId>377002</EventInstanceId>
        <OnSaleOnWeb>true</OnSaleOnWeb>
        <SeatsAvailable>343</SeatsAvailable>
        <SeatsLocked>164</SeatsLocked>
        <SeatsReserved>0</SeatsReserved>
        <SeatsSelected>0</SeatsSelected>
        <SeatsSold>2</SeatsSold>
        <Time>2019-08-02T19:00:00</Time>
        <WebInstanceId i:nil="true" />
    </EventTime>
    <EventTime>
        <Attributes>
            <EventAttribute>
                <Name>Venue</Name>
                <Value> Building 1</Value>
            </EventAttribute>
            <EventAttribute>
                <Name>Special Performance</Name>
                <Value />
            </EventAttribute>
        </Attributes>
        <Capacity>509</Capacity>
        <EventInstanceId>376803</EventInstanceId>
        <OnSaleOnWeb>true</OnSaleOnWeb>
        <SeatsAvailable>345</SeatsAvailable>
        <SeatsLocked>164</SeatsLocked>
        <SeatsReserved>0</SeatsReserved>
        <SeatsSelected>0</SeatsSelected>
        <SeatsSold>0</SeatsSold>
        <Time>2019-08-03T13:30:00</Time>
        <WebInstanceId i:nil="true" />
    </EventTime>
    <EventTime>
        <Attributes>
            <EventAttribute>
                <Name>Venue</Name>
                <Value> Building 1</Value>
            </EventAttribute>
            <EventAttribute>
                <Name>Special Performance</Name>
                <Value />
            </EventAttribute>
        </Attributes>
        <Capacity>509</Capacity>
        <EventInstanceId>377003</EventInstanceId>
        <OnSaleOnWeb>true</OnSaleOnWeb>
        <SeatsAvailable>345</SeatsAvailable>
        <SeatsLocked>164</SeatsLocked>
        <SeatsReserved>0</SeatsReserved>
        <SeatsSelected>0</SeatsSelected>
        <SeatsSold>0</SeatsSold>
        <Time>2019-08-03T19:00:00</Time>
        <WebInstanceId i:nil="true" />
    </EventTime>
    <EventTime>
        <Attributes>
            <EventAttribute>
                <Name>Venue</Name>
                <Value> Building 1</Value>
            </EventAttribute>
            <EventAttribute>
                <Name>Special Performance</Name>
                <Value />
            </EventAttribute>
        </Attributes>
        <Capacity>509</Capacity>
        <EventInstanceId>376804</EventInstanceId>
        <OnSaleOnWeb>true</OnSaleOnWeb>
        <SeatsAvailable>345</SeatsAvailable>
        <SeatsLocked>164</SeatsLocked>
        <SeatsReserved>0</SeatsReserved>
        <SeatsSelected>0</SeatsSelected>
        <SeatsSold>0</SeatsSold>
        <Time>2019-08-05T13:30:00</Time>
        <WebInstanceId i:nil="true" />
    </EventTime>
    <EventTime>
        <Attributes>
            <EventAttribute>
                <Name>Venue</Name>
                <Value> Building 1</Value>
            </EventAttribute>
            <EventAttribute>
                <Name>Special Performance</Name>
                <Value />
            </EventAttribute>
        </Attributes>
        <Capacity>509</Capacity>
        <EventInstanceId>376805</EventInstanceId>
        <OnSaleOnWeb>true</OnSaleOnWeb>
        <SeatsAvailable>345</SeatsAvailable>
        <SeatsLocked>164</SeatsLocked>
        <SeatsReserved>0</SeatsReserved>
        <SeatsSelected>0</SeatsSelected>
        <SeatsSold>0</SeatsSold>
        <Time>2019-08-06T13:30:00</Time>
        <WebInstanceId i:nil="true" />
    </EventTime>
</Times>
<WebEventId i:nil="true" />
</Event>

我正在使用这个 php 从 XML 文件中获取数据:

<?php
   $xml=simplexml_load_file("myxml.xl") or die("Error: Not Working");
    foreach($xml->Times->EventTime as $Times) {
        $filmdate =$Times->Time;
        $shortdate = date("D d M",strtotime(date($filmdate)));
        $filmtimenew = date("g.ia",strtotime(date($filmdate)));
    if( strtotime($filmdate) > strtotime('now') ) { 
        echo "<span>" . $shortdate . "</span>"; 
        echo "<a href='#'>" . $filmtimenew . "</a>";
        echo "<br>";
        }
    }
?> 

这是我得到的输出:
8 月 2 日星期五下午 1:30
8 月 2 日星期五晚上 7 点
8 月 3 日星期六下午 1:30
8 月 3 日星期六晚上 7 点
8 月 5 日星期一下午 1 点 30 分

但我想要没有重复日期的这个:
8 月 2 日星期五下午 7 点半
8 月 3 日星期六下午 7 点半
8 月 5 日星期一下午 1:30

我最初确实用 JQuery 隐藏了重复项,但我想正确地做到这一点。

这样做是建立一个包含所有日期和时间的列表,然后格式化输出(这在使用模板时也很有用)。

数组以日期为索引,每找到一个时间就添加一个新的时间。最后再输出日期,后面跟着这个数组的每个元素....

$dates = [];
foreach($xml->Times->EventTime as $Times) {
    $filmdate =$Times->Time;
    $shortdate = date("D d M",strtotime(date((string)$filmdate)));
    $filmtimenew = date("g.ia",strtotime(date((string)$filmdate)));
    if( strtotime((string)$filmdate) > strtotime('now') ) {
        $dates [ $shortdate ][] = $filmtimenew;
    }
}

foreach ( $dates as $date =>$times ) {
    echo "<span>" . $date . "</span>";
    foreach ( $times as $time ) {
        echo "<a href='#'>" . $time . "</a>";
        echo "<br>";
    }
}

正如所指出的,您需要确保文件正确加载,因为某些组件的格式不正确(<WebInstanceId i:nil="true" /> 中的 i 没有命名空间等)

还考虑 XSLT, the declarative, special-purpose language (same type as SQL) designed to transform XML files where you can run the Muenchian Method 使用 xsl:key.

按不同日期分组

PHP 可以 运行 XSLT 1.0 脚本及其 php-xsl library. And for your nuanced date formatting, use extended exslt and even PHP's own functions as they can be registered inside XSLT - 对我来说是全新的(张贴在这里供未来的读者使用)!

XSLT (另存为 .xsl 文件,一种特殊的 .xml 文件;使用两个扩展名来格式化日期)

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                              xmlns:date="http://exslt.org/dates-and-times"
                              xmlns:php="http://php.net/xsl">
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:key name="date_key" match="EventTime" use="date:date(Time)" />

    <xsl:template match="Event"> 
        <xsl:apply-templates select="Times"/>
    </xsl:template>

    <xsl:template match="Times">     
            <xsl:for-each select="EventTime[generate-id() =
                                       generate-id(key('date_key', date:date(Time))[1])]" >
                 <span><xsl:value-of select="concat(date:day-abbreviation(string(Time)), ' ', 
                                                    date:day-in-month(string(Time)), ' ',
                                                    date:month-abbreviation(string(Time))
                                                    )"/></span>
                 <xsl:for-each select="key('date_key', date:date(Time))" >
                     <a href="#">
                          <xsl:value-of select="php:function('date', 'g.ia', 
                                                             php:function('strtotime', 
                                                                          php:function('date', string(Time))
                                                             )
                                                )"/>
                     </a>
                     <br/>
                 </xsl:for-each> 
            </xsl:for-each>      
    </xsl:template>
</xsl:stylesheet>

PHP(没有for循环或if逻辑)

$xml = new DOMDocument;
$xml->load('Input.xml');

$xsl = new DOMDocument;
$xsl->load('Script.xsl');

// Configure transformer
$proc = new XSLTProcessor;
$proc->registerPHPFunctions();
$proc->importStyleSheet($xsl);

// Transform XML source
$newXML = new DOMDocument;
$newXML = $proc->transformToXML($xml);

// Output to console
echo $newXML;

输出

<span>Fri 2 Aug</span><a href="#">1.30pm</a><br/><a href="#">7.00pm</a><br/>
<span>Sat 3 Aug</span><a href="#">1.30pm</a><br/><a href="#">7.00pm</a><br/>
<span>Mon 5 Aug</span><a href="#">1.30pm</a><br/>
<span>Tue 6 Aug</span><a href="#">1.30pm</a><br/>