使用php计算每个日期在xml中每个id出现的频率

时间:2016-06-09 14:53:48

标签: php xml count

我只是想绕过它,但我感到迷茫。 我有一个这种结构的xml:

<Logs>
    <Log>
        <AppID>12345</AppID>
        <Module>String</Module>
        <Info>String</Info>
        <Date>Datetime</Date>
    </Log>
    <Log>
        ...
    </Log>
</Logs>

我需要的是一种输出,每天记录AppID的频率。 类似的东西:

20016-06-01: 12345: 5 times, 12557: 2 times
20016-06-02: 12345: 3 times, 18949: 1 times

我已经使用simple_xml来加载xml文件并使用:

进行处理
foreach ($loadedxml->Log as $error){...}

2 个答案:

答案 0 :(得分:0)

使用php,哈希表通常就是答案:

$res = array();
foreach ($loadedxml->Logs->Log as $curLog)
{
   if (!isset($res[(String)$curLog->Date]))
      $res[(String)$curLog->Date] = array();

   $lstLogDate = &$res[(String)$curLog->Date];
   if (!isset($lstLogDate[(String)$curLog->AppID])
      $lstLogDate[(String)$curLog->AppID] = 0;

   $lstLogDate[(String)$curLog->AppID]++;
}

此代码创建一个哈希表,其中所有日期都作为键,对于每个条目,都有一个列表填充,其中id为键,数字作为值出现。 下一个代码显示结果:

foreach ($res as $dateValue => $lstId)
{
   echo $dateValue . ": ";

   foreach ($lstId as $id => $countId)
     echo $id . ": " . $countId . "times";

   echo "\n";
}

答案 1 :(得分:0)

用于在XSLT 1.0中进行分组的Muenchian Method的经典示例。作为信息,XSLT(其脚本是格式良好的XML文档)是一种用于转换XML文件的专用语言。像大多数通用语言一样,PHP维护着一个XSLT 1.0处理器。

下面的XSLT脚本在<xsl:key><AppID>的串联上运行<Date>,然后计算不同的组值。实际上,XSLT可以在没有单个for循环的情况下输出字符串行!

XML 输入(对于可重现的示例)

<Logs>
    <Log>
        <AppID>12345</AppID>
        <Module>Falcon</Module>
        <Info>Avengers Assemble</Info>
        <Date>2016-06-01</Date>
    </Log>
    <Log>
        <AppID>12345</AppID>
        <Module>Captain America</Module>
        <Info>Avengers Assemble</Info>
        <Date>2016-06-01</Date>
    </Log>
    <Log>
        <AppID>12557</AppID>
        <Module>Black Widow</Module>
        <Info>Avengers Assemble</Info>
        <Date>2016-06-01</Date>
    </Log>
    <Log>
        <AppID>12345</AppID>
        <Module>Iron Man</Module>
        <Info>Avengers Assemble</Info>
        <Date>2016-06-02</Date>
    </Log>
    <Log>
        <AppID>12557</AppID>
        <Module>Hulk</Module>
        <Info>Avengers Assemble</Info>
        <Date>2016-06-02</Date>
    </Log>
    <Log>
        <AppID>12557</AppID>
        <Module>Blackhawk</Module>
        <Info>Avengers Assemble</Info>
        <Date>2016-06-01</Date>
    </Log>
    <Log>
        <AppID>12345</AppID>
        <Module>Thor</Module>
        <Info>Avengers Assemble</Info>
        <Date>2016-06-01</Date>
    </Log>
</Logs>

XSLT 脚本(另存为下载的.xsl文档)

<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="appkey" match="Log" use="concat(AppID, Date)" />

  <xsl:template match="Logs">        
      <xsl:apply-templates select="Log[generate-id() = 
                                       generate-id(key('appkey',concat(AppID, Date))[1])]">
        <xsl:sort select="concat(Date, AppID)"/>
      </xsl:apply-templates>        
  </xsl:template>

  <xsl:template match="Log[generate-id() = 
                           generate-id(key('appkey',concat(AppID, Date))[1])]">    
      <xsl:value-of select="concat(Date, ': ', AppID, ' ', 
                            count(. | key('appkey', concat(AppID, Date))), ' times')"/>
    <xsl:text>&#xA;</xsl:text>
  </xsl:template>

</xsl:transform>

PHP 脚本

// LOAD XML AND XSL FILES
$xmlfile = new DOMDocument('1.0', 'UTF-8');
$xmlfile->load('Input.xml');

$xslfile = new DOMDocument('1.0', 'UTF-8');
$xslfile->load('XSLTScript.xsl');

// TRANSFORM XML with XSLT
$proc = new XSLTProcessor;
$proc->importStyleSheet($xslfile); 
$newXml = $proc->transformToXML($xmlfile);

// ECHO OUTPUT STRING
echo $newXml;

# 2016-06-01: 12345 3 times
# 2016-06-01: 12557 2 times
# 2016-06-02: 12345 1 times
# 2016-06-02: 12557 1 times