【问题标题】:How to snag highest numbered XML item with PHP?如何使用 PHP 获取编号最高的 XML 项?
【发布时间】:2012-02-01 19:17:24
【问题描述】:

我基本上有一个包含产品信息的 XML 文件,可用于电子商务系统。我一直在创建一个脚本,将这些 XML 文件转换为 .CSV,数据以电子商务系统可以处理的格式结构化(因此我不需要在每次供应商提供新的 XML 文件时复制/粘贴列) .每个产品的类别定义如下:

<web_category1>3</web_category1>
<web_category2>1</web_category2>
<web_category3>6</web_category3>

web_category3 是商品的类别,1 和 2 是产品类别的父类别。问题是有些项目嵌套在 2 个类别下..或者有时是 5 个。所以我需要找到一种方法让 PHP 获取其后数字最高的 web_category,因为它始终是产品的类别。

谢谢!

【问题讨论】:

  • 他们总是这样按数字排序吗?所以 1、2 然后 3。或者它们也可以是 1、3 然后 2?
  • 总是1, 2, 3, 4, 5等。只需要抓取最高编号的web_category的值。
  • 恭喜你的第一篇文章;欢迎来到堆栈溢出,杰里米。
  • 谢谢!这是我多年来一直使用它的网站的功劳,直到现在才不得不问一个问题,因为我在其他地方找不到答案:P

标签: php xml


【解决方案1】:

@ben 的回答是正确的,但对我来说有点紧张。 SimpleXMLElement 对象很好,因为您可以轻松地将它们转换为数组。因此,更简单的解决方案是将其转换为数组并使用max 来确定结果数组中的最大值:

$str = '
<item>
    <web_category1>3</web_category1>
    <web_category2>1</web_category2>
    <web_category3>6</web_category3>
</item>
';

$xml = new SimpleXMLElement($str);
echo max((array)$xml); // outputs: 6

更新

根据您在下面的评论,假设您需要获取 XML 文件中出现的 &lt;item&gt; 元素的最大值所有,而不仅仅是一个(如上)。要处理这个问题,您可以使用 SimpleXMLElement::xpathdocs 获取所有出现的 &lt;item&gt; 的数组,然后在 xpath 结果的循环内执行相同的转换技巧:

$str = '
<xml>
  <product1>
    <item>
      <web_category1>3</web_category1>
      <web_category2>1</web_category2>
      <web_category3>6</web_category3>
    </item>
  </product1>
  <product2>
    <item>
      <web_category4>17</web_category4>
      <web_category5>0</web_category5>
    </item>
  </product2>
</xml>
';

$xml = new SimpleXMLElement($str);

$allItems = array();
$items = $xml->xpath('//item');
foreach($items as $item) {
  $allItems = array_merge($allItems, (array)$item);
}
echo max($allItems); // outputs: 17

更新 2

好的,上次。如果这不是你想要做的,你至少应该有足够的例子来从这里弄清楚。考虑:

$str = '
<xml>
  <product1>
    <web_category1>3</web_category1>
    <web_category2>1</web_category2>
    <web_category3>6</web_category3>
  </product1>
  <product2>
    <web_category4>17</web_category4>
    <web_category5>0</web_category5>
  </product2>
  <product3>
    <web_category6>17</web_category6>
    <web_category7>21</web_category7>
  </product3>
</xml>
';

$xml = new SimpleXMLElement($str);

// assumes that product node names start with "product"
$products = $xml->xpath("//*[starts-with(name(),'product')]");
foreach ($products as $p) {
  $catNames = array_keys((array)$p);
  $catNums  = preg_replace("/[^\d]/", "", $catNames);
  echo $p->getName() . ' - highest category: ' . max($catNums) . "\n";
}

以上代码输出如下:

product1 - highest category: 3
product2 - highest category: 5
product3 - highest category: 7

【讨论】:

  • 我喜欢这个,因为它要简单得多,但我会遇到的问题(请记住,我的 XML 术语已经过时了)是每个部分(每个产品)都有一个里面有几个 web_category 项目。介于 1 个 web_category 到喜欢 4 个左右。我将如何制作它,以便我的脚本提取每个产品的所有现有 web_category 项目并通过 max() 函数运行它们?
  • 我想我措辞错误。实在抱歉。我有一段时间(),其中每个产品都被写入 .CSV 中的不同行。所以我需要它来嗅出每个项目的最高#'d web_category 并将其输出到 csv 中该产品的行中。因此,如果产品 A 具有:web_category1 web_category2 web_category3 和 B 具有:web_category1 web_category2 我需要它从 A 中获取 web_cat3 并从 B 中获取 web_cat2。我希望这是有道理的......至少在我的脑海中是有道理的,哈哈
  • @JeremyDuenas 那么您是想从任何出现的&lt;web_category9&gt; 中获得最高值,还是只想知道9 是最高 出现的“web_category”节点?此外,数字9 always 会是节点名称中的最后一个字符吗?因为它影响了我的回答。
  • 我需要知道我的 while() 语句中每个产品出现的最高“web_category”节点是什么。所以我想我需要知道 9 是出现次数最多的 web_category 节点。不,9 并不总是节点中的最后一个字符。
  • 哦,伙计,我想我只是让它变得更加混乱。忽略最后一条评论中除了第一句话之外的所有内容。第一句话几乎可以说清楚地解释它。另外我的意思是它被包裹在一个 foreach() 中,而不是一个 while(),如果这很重要的话。
【解决方案2】:

假设你的 XML 是这样的:

<item>
    <web_category1>3</web_category1>
    <web_category2>1</web_category2>
    <web_category3>6</web_category3>
</item>

你有一个 &lt;item&gt; 的 SimpleXMLElement 对象,应该这样做:

$highest_web_category_number = -1;
$value_of_highest_web_category_number = -1;
foreach($item->getChildren() as $name => $data) {
    if(strpos($name, 'web_category') === 0) {
        $web_category_number = substr($name, strlen('web_category'));
        if($web_category_number > $highest_web_category_number) {
            $highest_web_category_number = $web_category_number
            $value_of_highest_web_category_number = $data;
        }
    }
}

【讨论】:

    猜你喜欢
    • 2022-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-16
    • 1970-01-01
    相关资源
    最近更新 更多