SimpleXML PHP Parsing [duplicate]

孤街醉人 提交于 2019-12-25 17:21:25

问题


It IS a duplicate, just not for the question that is was closed for. Finally found the answer, even here on SO. Actual Duplicate: PHP SimpleXML Namespace Problem

EDIT: If you read the question closely, you will see it is NOT a duplicate of PHP namespace simplexml problems. The answer from the 'possible duplicate' is not the answer to my question.

Again:
I have no problem with $value = $record->children('cap', true)->$title;.(which is all the 'possible duplicate' answers)
I have a problem when there are other tags inside the tag with the colon.

<tag:something>hello</tag:something> //I parse out hello (this is the 'duplicate questions' answer that I don't need answered)

<tag:something>
 <stuff>hello</stuff> //I cannot grab this. Explanation below.
</tag:something>

END of edit.

ORIGINAL question:
I cannot get the data inside the tag <value> in the XML located at http://alerts.weather.gov/cap/us.php?x=1 (sample of XML below).

The problem is at:

$array[] = $record->children($tag_cap, true)->$tag_geocode->$tag_value;

This is the only data I cannot grab, I have verified that all the other data other than $array[4] is grabbed.

There is just a problem getting data from tags when the parent tag is in the form <cap:something>. For example:

I can get 100 when it is like <cap:something>100</cap:something>. But I cant get 100 if it was like <cap:something><value>100</value></cap:something>.

Piece of the XML:

<?xml version = '1.0' encoding = 'UTF-8' standalone = 'yes'?>

<feed
xmlns = 'http://www.w3.org/2005/Atom'
xmlns:cap = 'urn:oasis:names:tc:emergency:cap:1.1'
xmlns:ha = 'http://www.alerting.net/namespace/index_1.0'
>
<!-- http-date = Tue, 30 Oct 2012 06:34:00 GMT -->

<id>http://alerts.weather.gov/cap/us.atom</id>
<logo>http://alerts.weather.gov/images/xml_logo.gif</logo>
<generator>NWS CAP Server</generator>
<updated>2012-10-30T14:34:00-04:00</updated>
<author>
<name>w-nws.webmaster@noaa.gov</name>
</author>
<title>Current Watches, Warnings and Advisories for the United States Issued by the    National Weather Service</title>
<link href='http://alerts.weather.gov/cap/us.atom'/>

<entry>
<id>http://alerts.weather.gov/cap/wwacapget.php?x=AK124CCADA8120.BlizzardWarning.124CCAE7BFC0AK.AFGWSWNSB.d32adb45b5c82ec5e486c4cfb96d3fb6</id>
<updated>2012-10-30T05:20:00-08:00</updated>
<published>2012-10-30T05:20:00-08:00</published>
<author>
<name>w-nws.webmaster@noaa.gov</name>
</author>
<title>Blizzard Warning issued October 30 at 5:20AM AKDT until October 31 at 6:00AM AKDT by NWS</title>
<link href='http://alerts.weather.gov/cap/wwacapget.php?x=AK124CCADA8120.BlizzardWarning.124CCAE7BFC0AK.AFGWSWNSB.d32adb45b5c82ec5e486c4cfb96d3fb6'/>
<summary>...BLIZZARD WARNING IN EFFECT UNTIL 6 AM AKDT WEDNESDAY... THE NATIONAL WEATHER SERVICE IN FAIRBANKS HAS ISSUED A BLIZZARD WARNING...WHICH IS IN EFFECT UNTIL 6 AM AKDT WEDNESDAY. * VISIBILITY...NEAR ZERO IN SNOW AND BLOWING SNOW. * WINDS...WEST 35 MPH GUSTING TO 50 MPH. * SNOW...ACCUMULATION 3 INCHES THROUGH TONIGHT.</summary>
<cap:event>Blizzard Warning</cap:event>
<cap:effective>2012-10-30T05:20:00-08:00</cap:effective>
<cap:expires>2012-10-30T16:00:00-08:00</cap:expires>
<cap:status>Actual</cap:status>
<cap:msgType>Alert</cap:msgType>
<cap:category>Met</cap:category>
<cap:urgency>Expected</cap:urgency>
<cap:severity>Severe</cap:severity>
<cap:certainty>Likely</cap:certainty>
<cap:areaDesc>Eastern Beaufort Sea Coast</cap:areaDesc>
<cap:polygon></cap:polygon>
<cap:geocode>
<valueName>FIPS6</valueName>
<value>002185</value>
<valueName>UGC</valueName>
<value>AKZ204</value>
</cap:geocode>
<cap:parameter>
<valueName>VTEC</valueName>
<value>/X.NEW.PAFG.BZ.W.0013.121030T1320Z-121031T1400Z/</value>
</cap:parameter>
</entry>

...//rest of XML...

PHP Code:

ini_set('display_errors','1');

$alert_url = 'http://alerts.weather.gov/cap/us.php?x=1';

$alert_string_xml = file_get_contents($alert_url);

$alert_simple_xml_object = simplexml_load_string($alert_string_xml);

$count = 0;

$tag_entry = 'entry';
$tag_summary = 'summary';
$tag_cap = 'cap';
$tag_event = 'event';
$tag_certainty = 'certainty';
$tag_areaDesc = 'areaDesc';
$tag_geocode = 'geocode';
$tag_value = 'value';

foreach ($alert_simple_xml_object->$tag_entry as $record)
{
    $count++;

    $array = array();
    $array[] = $record->$tag_summary;
    $array[] = $record->children($tag_cap, true)->$tag_event;
    $array[] = $record->children($tag_cap, true)->$tag_certainty;
    $array[] = $record->children($tag_cap, true)->$tag_areaDesc;
    $array[] = $record->children($tag_cap, true)->$tag_geocode->$tag_value;
    //$array[] = $record->children($tag_cap, true)->$tag_geocode->$tag_value[0]; //doesnt work either


    echo $array[4]; //nothing is echoed

}

MOST CURRENT ATTEMPT:
I read more on namespaces and understand them better. I even tried what I thought was a better solution:

//inside the above foreach loop
    $namespaces = $record->getNameSpaces(true);
    $caap = $record->children($namespaces['cap']);
    echo $caap->event; //works (but the first way works too)
    echo $caap->geocode->value; //(STILL does not work. Nothing is echoed)

I don't understand why I cannot grab any data from children tags that have a parent tag that includes a namespace.


回答1:


cap:stuff is the root, so you would access the elements as:

$xml = simplexml_load_string($your_xml);
$value_name_0 = $xml->valueName[0];
$value_0 = $xml->value[0];
$value_name_1 = $xml->valueName[1];
$value_1 = $xml->value[1];



回答2:


You are probably looking for this function. There are 2 examples, which should be enough to solve your problem




回答3:


The problem you are facing is not that visible if you have errors and warnings disabled:

namespace error : Namespace prefix cap on stuff is not defined

If you would have errors enable you would see that message. Because simplexml is not able to parse the namespace prefix cap properly, it will be dropped.

Therefore you access it directly:

$xml->stuff->value[1]

And similar. Consider the following code-example (demo:

$xml = simplexml_load_string('<entry>
 <cap:stuff>
  <valueName>aaa</valueName>
  <value>000</value>
  <valueName>bbb</valueName>
  <value>111</value>
 </cap:stuff>
</entry>');

echo "\nResult:", $xml->stuff->value[1], "\n\n";
echo "XML:\n", $xml->asXML();

It demonstrates the error message as well what is in $xml after loading the XML string by outputting it:

Warning: simplexml_load_string(): namespace error : Namespace prefix cap on \ 
                                  stuff is not defined on line 10
Warning: simplexml_load_string():  <cap:stuff> on line 10
Warning: simplexml_load_string():            ^ on line 10

Result:111

XML:
<?xml version="1.0"?>
<entry>
 <stuff>
  <valueName>aaa</valueName>
  <value>000</value>
  <valueName>bbb</valueName>
  <value>111</value>
 </stuff>
</entry>

If you smell that something should work but it isn't, it is always necessary to look closer. One option is to echo the string again as XML to see what simplexml has parsed, the other is to enable error reporting and looking for warnings and error, they often contain further information.



来源:https://stackoverflow.com/questions/13178873/simplexml-php-parsing

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!