2

我有一个使用 PHP 的 Simplexml 解析的 XML 文件,但是我在通过节点进行迭代时遇到了问题。

XML:

<channel>
  <item>
    <title>Title1</title>
    <category>Cat1</category>
  </item>
  <item>
    <title>Title2</title>
    <category>Cat1</category>
  </item>
  <item>
    <title>Title3</title>
    <category>Cat2</category>
  </item>
</channel>

我的计数功能:

public function cat_count($cat) {
    $count = 0;
    $items = $this->xml->channel->item;
    $size  = count($items);

    for ($i=0; $i<$size; $i++) {
        if ($items[$i]->category == $cat) {
            $count++;
        }
    }
    return $count;
}

我是否忽略了代码中的错误,或者是否有另一种用于迭代节点的首选方法?我还使用了 foreach 和 while 语句,但没有运气,所以我很茫然。有什么建议么?

编辑:在使用下面的 xpath 方法时,我注意到使用

foreach ($this->xml->channel->item as $item) {
    echo $item->category;
}

将打印所有类别名称,但是,使用

foreach ($this->xml->channel->item as $item) {
    if ($item->category == $cat) {
        echo $item->category;
    }
}

只会打印加倍类别的一个实例。即使我复制并粘贴了线条,也只有一个显示。这是否意味着 XML 结构可能以某种方式无效?

4

1 回答 1

1

在 XML 文件中计算具有给定名称的元素的一种简单方法是使用 xpath。尝试这个:

private function categoryCount($categoryName) {
    $categoryName = $this->sanitize($categoryName); // easy xpath injection protection
    return count($this->xml->xpath("//item[category='$categoryName']"));
}

sanitize() 函数应该删除单引号和双引号$categoryName以防止 xpath 注入。要同时获取包含引号的类别名称的查询,您需要根据它包含单引号或双引号来构建您的 xpath 查询字符串:

// xpath in case of single quotes in category name
$xpath = '//item[category="' . $categoryName . '"]';

// xpath in case of double quotes in category name
$xpath = "//item[category='" . $categoryName . "']";

如果您无法完全控制 xml 数据(例如,如果是根据用户生成的内容创建的),您应该考虑到这一点。不幸的是,在 php 中没有像参数化查询这样的简单方法。

有关 php xpath 函数文档,请参见此处:http: //php.net/manual/en/simplexmlelement.xpath.php

请参阅此处以获取 xpath 参考: http ://www.w3schools.com/xpath/xpath_syntax.asp

于 2013-10-19T22:30:22.700 回答