1

I am new with PHP simplexml code, and I've found that the code does provide results for the variable $xml_record_congrant_funded.

I've tried adding namespace identifiers (please see commented out code), but there is no result - it returns "Undefined offset: 0".

Would there need to be some kind of modification to the namespace identifiers? Thanks for any leads.

PHP file:

$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 File:

<?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>

1 Answer 1

1

As you use XPath on an individual node in SimpleXML, you have to register the namespace each time you want to use it, and as all of the nodes are in a default namespace (which you have used a as a prefix in your code) you need to keep adding it.

So in the second XPath, you need to register the same namespace on $xml_record[0] to then use this as a prefix in the expression '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;

Also note that you need to use the same case for the object elements as in the XML - so it's $xml_record_congrant_funded[0]->STATUS.

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks. For the default namespace, if, for example, I chose not to use a prefix, would I still need to register the namespace?
If you don't use a prefix, then no need to register it. Just remember that anything in the default namespace is still in a namespace although it doesn't have a prefix (I hope that makes sense :-/)
Thanks. I've been removing that prefix, where it occurs, as a test. Although the XML document does not specify the 'a', when I remove the 'a' references throughout the document, I get the 'undefined offset' in line 19 ( $xml_record[0]['username']. )
When you use registerXPathNamespace() you can use any prefix you want, the important part is the second parameter MUST match the one defined in the document. So if the element in the document is in the namespace, then you need to match this in your XPath.
No - you need to register it and use the prefix you've defined (hence the need for a: in the XPath).
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.