【问题标题】:PHP 5: Return closest 5 results to a search value from an XMLPHP 5:从 XML 中返回最接近搜索值的 5 个结果
【发布时间】:2012-07-13 14:27:07
【问题描述】:

我有一个由第三方提供的XML,我无法控制其格式。它看起来像这样:

<base>  
    <results index="1">  
        <quote vendor_name="Company X">  
            <quote_detail rate="3.375" price="-0.440">  
                <stuff>value</stuff>  
            </quote_detail>  
        </quote>  
    </results>  
    <results index="2">  
        <quote vendor_name="Company y">  
            <quote_detail rate="3.548" price="-0.230">  
                <stuff>value</stuff>  
            </quote_detail>  
        </quote>  
    </results>  
    <results index="3">  
        <quote vendor_name="Company Z">  
            <quote_detail rate="3.799" price="1.120">  
                <stuff>value</stuff>  
            </quote_detail>  
        </quote>  
    </results>  
</base>

我需要做的是返回价格最接近零的结果(vendor_namerateprice),而不超过以及上下两个。理想的结果应该是这样的(中间的最接近零):

  1. 公司 Z / 3.875 / -1.375
  2. 公司 Y / 3.750 / -0.875
  3. 公司 X / 3.375 / -0.440
  4. A公司 / 3.500 / 0.250
  5. 公司 B / 3.375 / 1.125

我不确定执行此操作所需的逻辑或如何在运行所述逻辑时保留XML 信息。有什么帮助吗?

【问题讨论】:

  • A 公司不是比 X 公司更接近于零吗?
  • 不知道是否可以对 XML 进行排序,但您可以将其放入数组中,ksort 它并输出前 5 个变量。
  • @DainisAbols 建议一个好的开始,我认为这个问题不属于这里。你给出了一个起点,一个期望的终点,但在这两者之间没有任何解决办法
  • 你可以使用XQuery,这个问题可能对你有帮助stackoverflow.com/q/2211743/1105514

标签: php xml xml-parsing


【解决方案1】:

我只是为您提供一些链接以帮助您入门。

请查看simpleXML 以使用 php 对象访问 xml 数据。 cmets 中的 XQuery Hint 也为您指明了这个方向。

在遍历结果时,您可以将奖品的绝对值保存在一个数组中,并使用ksort 对其进行排序。

【讨论】:

  • 这不是答案,也不会为 cmets 中尚未说明的问题增加任何价值。
  • @nickb,你是对的。除了使用绝对值的提示之外,没有什么新东西。
【解决方案2】:

您需要做的是从 XML 中解析出数据以便能够使用它。然后,一旦你有了数据,你就可以选择你需要的公司。

这是一个使用 PHP 的 DOMDocument 类的主要工作解决方案。首先,首先将公司解析为一个数组:

$doc = new DOMDocument;
$doc->loadXML( $xml); // $xml = your string from above

$xpath = new DOMXPath( $doc);

$companies = array();
foreach( $xpath->query('//results') as $result) {
    $quote = $xpath->query( 'quote', $result)->item(0);
    $vendor_name = $quote->attributes->getNamedItem( 'vendor_name')->value;

    $quote_detail = $xpath->query( 'quote_detail', $quote)->item(0);
    $rate = $quote_detail->attributes->getNamedItem( 'rate')->value;
    $price = $quote_detail->attributes->getNamedItem( 'price')->value;

    $companies[] = array( 
        'vendor_name' => $vendor_name,
        'rate' => $rate,
        'price' => $price
    );
}

var_dump( $companies);

现在,您有一个公司数组,类似于:

array(3) {
  [0]=>
  array(3) {
    ["vendor_name"]=>
    string(9) "Company X"
    ["rate"]=>
    string(5) "3.375"
    ["price"]=>
    string(6) "-0.440"
  }
  [1]=>
  array(3) {
    ["vendor_name"]=>
    string(9) "Company y"
    ["rate"]=>
    string(5) "3.548"
    ["price"]=>
    string(6) "-0.230"
  }
  [2]=>
  array(3) {
    ["vendor_name"]=>
    string(9) "Company Z"
    ["rate"]=>
    string(5) "3.799"
    ["price"]=>
    string(5) "1.120"
  }
}

然后,对价格字段中的公司列表进行排序。

usort( $companies, function( $a, $b) { 
    if( $a['price'] == $b['price']) 
        return 0; 
    return $a['price'] < $b['price'] ? -1 : 1;
});

var_dump( $companies);

您的示例数据已经排序,所以这最终什么都不做。但是,您需要一个排序数组才能确定哪些最接近于零。

从这里开始,您必须弄清楚如何选择所需的 5 个元素。我认为这不仅仅是开始所需要的。

【讨论】:

  • 如果您需要考虑到负值的最接近 0 的价格值,您需要在比较函数中使用 abs($price)。否则你会在排序后的数组中找到最低的负值。
  • 这将是完整的工作解决方案,我并没有说我正在生产 :) OP 可以完成一些的工作。
猜你喜欢
  • 2011-09-22
  • 1970-01-01
  • 1970-01-01
  • 2011-04-24
  • 2014-04-21
  • 1970-01-01
  • 1970-01-01
  • 2021-09-05
  • 1970-01-01
相关资源
最近更新 更多