【问题标题】:simplexml finding value of node using xpath with xpathnamespace - undefined offset: 0simplexml 使用带有 xpathnamespace 的 xpath 查找节点的值 - 未定义的偏移量:0
【发布时间】:2020-01-30 03:06:38
【问题描述】:

我是 PHP simplexml 代码的新手,我发现该代码确实为变量 $xml_record_congrant_funded 提供了结果。

我尝试添加命名空间标识符(请参阅注释掉的代码),但没有结果 - 它返回“未定义偏移量:0”。

是否需要对命名空间标识符进行某种修改? 感谢您提供任何线索。

PHP 文件:

$url_congrant_file = "test.xml";

$xml_congrant_feed = simplexml_load_file($url_congrant_file);
$xml_congrant_feed->registerXPathNamespace('a','http://www.digitalmeasures.com/schema/data');//
$xml_congrant_feed->registerXPathNamespace('dmd','http://www.digitalmeasures.com/schema/data-metadata');

$username="bill-smith";
$username=strtolower($username); 
$xml_record=$xml_congrant_feed->xpath('//a:Record[contains(translate(@username,"ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz"),"'.$username.'")]');

echo '<br>$xml_record[0] is...'.$xml_record[0]['username'];

$xml_record_congrant_funded = $xml_record[0]->xpath('CONGRANT[STATUS="Funded"]');
//$xml_record_congrant_funded = $xml_record[0]->xpath('./dmd:CONGRANT[STATUS="Funded"]');
//this needs to store all 'congrant' nodes with the status of "funded" 

echo '<br>$xml_record_congrant_funded[0] is...'.$xml_record_congrant_funded[0]->status;
//this needs to display the value of the 'status' node


//I've put in the actual constants for the $offset (0), $per_page (2)   
for ($i = 0; $i < (0 + 2); $i++) {
        echo '<br>$i is...'.$i;
        $strCongrant_id = $xml_record_congrant_funded[$i]->ident;
        echo '<br>$strCongrant_id...'.$strCongrant_id;
        $strCongrant_status = $xml_record_congrant_funded[$i]->status;
        echo '<br>$strCongrant_id...'.$strCongrant_status;
        //this yields no results 
}   
var_dump($xml_record_congrant_funded);
print_r($xml_record_congrant_funded);

XML 文件:

<?xml version="1.0" encoding="utf-8"?>
<Data xmlns="http://www.digitalmeasures.com/schema/data" xmlns:dmd="http://www.digitalmeasures.com/schema/data-metadata" dmd:date="2019-09-09">
    <Record userId="9a" username="bill-smith" termId="2" dmd:surveyId="1">
        <dmd:IndexEntry indexKey="DE" entryKey="S7" text="S7"/>
        <CONGRANT id="12" dmd:originalSource="MA" dmd:created="2018-03-30T14:22:43" dmd:lastModifiedSource="MA" dmd:lastModified="2019-02-19T10:49:07" dmd:startDate="2017-08-08" dmd:endDate="2022-07-31">
            <TYPE>Book Grant</TYPE>
            <TITLE>Modulation Theory</TITLE>
            <STATUS>Funded</STATUS>
        </CONGRANT>
        <CONGRANT id="11" dmd:originalSource="MA" dmd:created="2019-07-05T10:14:55" dmd:lastModifiedSource="MA" dmd:lastModified="2019-07-05T10:17:44" dmd:startDate="2019-06-15" dmd:endDate="2019-06-15">
            <TYPE>Digital Grant</TYPE>
            <TITLE>Frequency Modulation</TITLE>
            <STATUS/>
        </CONGRANT>
        <CONGRANT id="16" dmd:originalSource="MA" dmd:created="2018-03-26T11:39:42" dmd:lastModifiedSource="MA" dmd:lastModified="2018-03-26T11:40:15" dmd:startDate="2017-10-04" dmd:endDate="2017-10-04">
            <TYPE>Book Grant</TYPE>
            <TITLE>Ferrite Curves</TITLE>
            <STATUS>Currently Under Review</STATUS>
        </CONGRANT>
    </Record>
</Data>

【问题讨论】:

    标签: php xml xpath simplexml xml-namespaces


    【解决方案1】:

    当您在 SimpleXML 中的单个节点上使用 XPath 时,您必须在每次要使用它时注册名称空间,并且所有节点都位于默认名称空间中(您使用 a 作为前缀在您的代码中)您需要继续添加它。

    所以在第二个 XPath 中,您需要在 $xml_record[0] 上注册相同的命名空间,然后将其用作表达式 'a:CONGRANT[a:STATUS="Funded"]' 中的前缀...

    $xml_record[0]->registerXPathNamespace('a','http://www.digitalmeasures.com/schema/data');//
    $xml_record_congrant_funded = $xml_record[0]->xpath('a:CONGRANT[a:STATUS="Funded"]');
    
    echo '<br>$xml_record_congrant_funded[0] is...'.$xml_record_congrant_funded[0]->STATUS;
    

    另请注意,您需要对对象元素使用与 XML 中相同的大小写 - 所以它是 $xml_record_congrant_funded[0]-&gt;STATUS。

    【讨论】:

    • 谢谢。对于默认命名空间,例如我选择不使用前缀,是否还需要注册命名空间?
    • 如果不使用前缀,则无需注册。请记住,默认命名空间中的任何内容仍然在命名空间中,尽管它没有前缀(我希望这是有道理的:-/)
    • 谢谢。作为测试,我一直在删除它出现的前缀。尽管 XML 文档没有指定“a”,但当我删除整个文档中的“a”引用时,我在第 19 行得到了“未定义的偏移量”($xml_record[0]['username'].)
    • 当您使用registerXPathNamespace() 时,您可以使用任何您想要的前缀,重要的部分是第二个参数必须匹配文档中定义的那个。因此,如果文档中的元素在命名空间中,那么您需要在 XPath 中匹配它。
    • 否 - 您需要注册它并使用您定义的前缀(因此需要在 XPath 中使用:)。
    猜你喜欢
    • 2018-06-17
    • 1970-01-01
    • 2014-06-25
    • 2013-09-23
    • 1970-01-01
    • 2012-02-08
    • 2020-01-02
    • 2021-07-06
    相关资源
    最近更新 更多