【问题标题】:PHP sorting an XML structurePHP 对 XML 结构进行排序
【发布时间】:2017-11-27 11:14:43
【问题描述】:

,大家好!

我有一个 XML 结构,我试图按子字段排序,然后我想要设置样式。我想我想问一下关于对对象进行排序的问题,但由于这并不是我真正要在可交付成果方面工作的目标:-)

XML 看起来很像

<messages>
  <message>
    <headers>
      <From>person</From>
      <Date>2014-10-09 19:46:37</Date>
      ...
      <Message-Id>long_id_string@server.dom.ain</Message-Id>
    </headers>
    <attachments>
      <attachment mimetype="image/jpeg" name="att1.jpg" output="/path/to/image"/>
      <attachment mimetype="text/plain" name="file.txt" output="/path/to/file"/>
    </attachments>
    <body>
      Message body here.  It might
      wrap, or it might not.
    </body>
  </message>
  <message>
    <headers>
      <From>person</From>
      <Date>2016-01-01 00:00:00</Date>
      ...
      <Message-Id>other_message_string@server.dom.ain</Message-Id>
    </headers>
    <attachments/>
    <body>
      A simple message
    </body>
  </message>
  <message>
    <headers>
      <From>HTML email sender</From>
      <Date>2015-06-06 01:23:45</Date>
      ...
      <Message-Id>horrible_idea@html.mail.ser.ver</Message-Id>
    </headers>
    <attachments/>
    <body>
      <div dir="ltr"><div class="gmail_default" style="font-size:small;color:#073763">Good afternoon David &amp; Laura!</div><div class=...
    </body>
  </message>
</messages>

(当然,虽然它非常缩写,而且更漂亮),我想对 message->headers->Date 字段进行排序。

我已经从这里和那里获取了一些代码,并且我能够将结构吸进一个带有 xml2array 和 XMLtoArray 函数的数组中,我已经提升了我的入门(但还没有关于何时吐出 XML 的消息我已经完成了;我还没有走那么远)。它们不如 SimpleXMLElement 漂亮

$msgobj = new SimpleXMLElement($msgxml)

结构,但是,这让我回到尝试对对象进行排序。我所做的所有谷歌搜索都涵盖了如何对对象数组而不是单个复杂对象进行排序。我确实看到 reference 到 XSLT 神奇地排序,但我完全迷失在那里(什么处理它?排序的内容去哪里?...)。

我最终希望将 XML 吐出——每条​​消息具有相同的结构和所有相同的字段——按日期排序,并且我希望为下一步应用一些样式到标题和正文。鉴于此,1) 最简单和最好的工作结构是什么,以及 2) 生锈的 PHP 黑客入门的正确方法是什么?

TIA 和汉威

:-D

【问题讨论】:

    标签: php arrays xml sorting object


    【解决方案1】:

    确实,请考虑XSLT,这是一种特殊用途的声明性语言(与 SQL 相同的类型),旨在转换 XML 文件,例如排序。就像 PHP 可以运行 SQL(或者更确切地说,通过 API 将 SQL 调用发送到数据库引擎,例如 PDO/mysqli)一样,PHP 可以使用其内置的 php-xsl 类将 XSLT 1.0 脚本发送到 XSLT 处理器 (libxslt)。

    XSLT (在下面另存为 .xsl 脚本或字符串变量,这是一个格式良好的 .xml 文件)

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output indent="yes"/>
      <xsl:strip-space elements="*"/>
    
      <xsl:template match="/messages">
        <xsl:copy>
          <xsl:apply-templates select="message">
            <xsl:sort select="headers/Date"/>
          </xsl:apply-templates>
        </xsl:copy>
      </xsl:template>
    
      <xsl:template match="message">
        <xsl:copy>
            <xsl:copy-of select="*"/>
        </xsl:copy>
      </xsl:template>
    
    </xsl:stylesheet>
    

    PHP (在加载输入xml和xsl下面运​​行,确保在.ini文件中启用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);
    

    输出 (缩写 &lt;div... 已被删除以用于格式良好的 XML)

    <?xml version="1.0" encoding="utf-8"?>
    <messages>
      <message>
        <headers>
          <From>person</From>
          <Date>2014-10-09 19:46:37</Date>
          <Message-Id>long_id_string@server.dom.ain</Message-Id>
        </headers>
        <attachments>
          <attachment mimetype="image/jpeg" name="att1.jpg" output="/path/to/image" />
          <attachment mimetype="text/plain" name="file.txt" output="/path/to/file" />
        </attachments>
        <body>
          Message body here.  It might
          wrap, or it might not.
        </body>
      </message>
      <message>
        <headers>
          <From>HTML email sender</From>
          <Date>2015-06-06 01:23:45</Date>
          <Message-Id>horrible_idea@html.mail.ser.ver</Message-Id>
        </headers>
        <attachments />
        <body>
          <div dir="ltr">
            <div class="gmail_default" style="font-size:small;color:#073763">Good afternoon David &amp; Laura!</div>
          </div>
        </body>
      </message>
      <message>
        <headers>
          <From>person</From>
          <Date>2016-01-01 00:00:00</Date>
          <Message-Id>other_message_string@server.dom.ain</Message-Id>
        </headers>
        <attachments />
        <body>
          A simple message
        </body>
      </message>
    </messages>
    

    【讨论】:

    • 天哪!看起来棒极了。我现在要开始自己尝试了。谢谢!!!敬请期待。
    • 是的!太棒了;我到处玩,能够以几种不同的方式进行排序;呜呼。再次感谢!我必须返回并在我的 IMAP 拉取脚本中重新处理一些处理(将 HTML 正文内容展平为纯文本),然后我将重新学习如何通过 XSLT 应用样式并遍历对象。更多学习乐趣 :-)
    • 非常好听!实际上,您可以使用 XSLT 扩展样式,因为它可以将 XML 转换为其他 XML、HTML 甚至文本 (CSV)!快乐编码。很高兴我能帮上忙。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-14
    • 2020-11-23
    • 2013-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多