php - 按日期排序 XML 数据输出

标签 php 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>

等等

有没有办法修改循环以获得这个结果?我将非常感谢任何帮助!

最佳答案

考虑XSLT ,旨在转换 XML 文件的专用语言,因为您实际需要的是名为 Muenchian Grouping 的 XSLT 1.0 方法。您可以在其中使用文档键按节点进行分组并检索或操作所有相应的值。

PHP 可以使用其 php-xsl 运行 XSLT 1.0 脚本扩展名(确保在 .ini 文件中启用)。使用这种方法,不需要 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>

关于php - 按日期排序 XML 数据输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45942596/

相关文章:

php - laravel 更新 session 数组中的值

.net - 如何在 Entity Frameworks 4.0 模型中指定 SQL Server XML 数据类型?

java - 如何在 java 中使用 jdom 更改 xml 的内部节点的值

java - Jersey 将我的 mysql 时间戳写为 2011-09-28T21 :48:25Z how do I format it in Java?

Javascript数组没有完全分配给php数组

php - EasyPHP 开发服务器 : database server not starting

javascript - 在 php 中导航,焦点问题

php - symfony - jquery 日期时间选择器

xml - Flutter/Dart XML添加和插入节点

java - 排除 xpath 表达式中的子元素