【问题标题】:Using Simplexml's Xpath to filter nodes based upon value in PHP使用 Simplexml 的 Xpath 根据 PHP 中的值过滤节点
【发布时间】:2019-11-30 21:30:36
【问题描述】:

我正在研究一种基于它们在 PHP 中的值来过滤某些节点的方法。我正在尝试返回等于“已资助”的状态节点的计数。 我不确定的部分是使用数组(新过滤器 ($xml_bio_children) 中前一个过滤器 ($xml_bio_record[0]) 的结果)。
此代码不返回 $count_c 的计数。我将如何过滤 status="Funded"?感谢您提供任何线索。

这是 XML:

<?xml version="1.0" encoding="utf-8"?>
<data>
<record id="1A">
    <congrant>
        <ident>a</ident>
        <status>Not Funded</status>
    </congrant>
    <congrant>
        <ident>b</ident>
        <status>Funded</status>
    </congrant>
    <congrant>
        <ident>c</ident>
        <status/>
    </congrant>
</record>
<record id="1B">
    <congrant>
        <ident>a</ident>
        <status>Not Funded</status>
    </congrant>
    <congrant>
        <ident>b</ident>
        <status>Funded</status>
    </congrant>
    <congrant>
        <ident>c</ident>
        <status/>
    </congrant>
</record>
<record id="1C">
    <congrant>
        <ident>aaa</ident>
        <status>Funded</status>
    </congrant>
    <congrant>
        <ident>bbb</ident>
        <status>Funded</status>
    </congrant>
    <congrant>
        <ident>c</ident>
        <status>Funded</status>
    </congrant>
</record>
</data>

这里是 PHP:

$url_bio = "test.xml";


$xml_bio = simplexml_load_file($url_bio);

$xml_bio_record=$xml_bio->xpath('/data/record');
$count_a = count($xml_bio_record);
echo '<br>$count_a is...'.$count_a.'<br>';//
foreach($xml_bio_record as $xa){
    echo "Found {$xa->status} <br>";
}

$xml_bio_record=$xml_bio->xpath('//record[@id="1A"]');
$count_b = count($xml_bio_record);
echo '<br>$count_b is...'.$count_b.'<br>';//
foreach($xml_bio_record as $xb){
    echo "Found {$xb->status} <br>";
}



$xml_bio_children=$xml_bio_record[0]->xpath('/congrant[status="Funded"]');

$count_c = count($xml_bio_children);
echo '<br>$count_c is...'.$count_c.'<br>';//
foreach($xml_bio_children as $xc){
    echo "Found {$xc->status} <br>";
}

======= 作为对此的补充,如果我希望设置一个等于$xb-&gt;xpath('./congrant[status="Funded"]') 的变量,例如:$xml_congrant_congrant_children=$xb-&gt;xpath('./congrant[status="Funded"]'),然后在分页场景中使用索引来循环通过资助结果,那如何实现? 例如

for ($i = $offset; $i < ($offset + $per_page); $i++)
 { 
$strCongrant_ident = $xml_congrant_congrant_children[$i]['ident'];
} 

我之前在分页设置中使用过这个循环的想法,但是在这里让过滤器应用于变量是行不通的。感谢您提供任何线索。

【问题讨论】:

    标签: php xml xpath simplexml


    【解决方案1】:

    正如supputuri's answer 建议的那样,您可以将两个 XPath 表达式组合成一个搜索:

    //record[@id="1A"]/congrant[status="Funded"]
    

    如果你想要第一个列表用于其他目的,你可以遍历它并在 PHP 中进行状态检查:

    $xml_bio_record=$xml_bio->xpath('//record[@id="1A"]');
    $funded_count = 0;
    foreach($xml_bio_record as $xb){
        foreach ($xb->congrant as $congrant) {
            if ( (string)$congrant->status == 'Funded' ) {
                $funded_count++;
            }
        }
    }
    

    或者您可以混合使用循环和 XPath,使用 . 使 XPath 搜索相对于特定元素:

    $xml_bio_record=$xml_bio->xpath('//record[@id="1A"]');
    $total_funded_count = 0;
    foreach($xml_bio_record as $xb){
        $xb_funded_count = count($xb->xpath('./congrant[status="Funded"]'));
        $total_funded_count += $xb_funded_count;
    }
    

    【讨论】:

    • 谢谢 - 我对我的原始问题做了一个附录,关于如何在分页设置中设置过滤器。
    • @buck1112 这个网站的设计目的是在每一页的顶部有一个问题,在下面有答案,所以如果你有跟进,它们可能应该是新帖子。否则,无法显示哪些答案回答了问题的哪些部分,这一切都会变得有点混乱。
    【解决方案2】:

    这里是纯 xpath,您可以使用它来获取具有Funded 状态的元素的数量。

    count(//record[@id="1A"]//status[.='Funded'])
    

    截图:

    【讨论】:

    • 很遗憾,SimpleXML's xpath method 只能返回元素和属性,因此不能与count() 一起使用。不过,只需获取 //record[@id="1A"]//status[.='Funded'] 的结果,然后在 PHP 中计算它们就可以了。
    猜你喜欢
    • 2012-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    相关资源
    最近更新 更多