使用 php SimpleXML 解析 XML 命名空间

Posted

技术标签:

【中文标题】使用 php SimpleXML 解析 XML 命名空间【英文标题】:Parse XML namespaces with php SimpleXML 【发布时间】:2013-04-30 23:50:48 【问题描述】:

我知道这个问题已经被问过很多次了,但我无法获得任何适合我的情况的建议,我已经搜索了网络和这里,尝试了所有方法,但没有任何效果。我只需要使用命名空间 cap: 解析这个 XML,并且只需要其中的四个条目。

<?xml version="1.0" encoding="UTF-8"?>
<entry>
    <id>http://alerts.weather.gov/cap/wwacapget.php?x=TX124EFFB832F0.SpecialWeatherStatement.124EFFB84164TX.LUBSPSLUB.ac20a1425c958f66dc159baea2f9e672</id>
    <updated>2013-05-06T20:08:00-05:00</updated>
    <published>2013-05-06T20:08:00-05:00</published>
    <author>
        <name>w-nws.webmaster@noaa.gov</name>
    </author>
    <title>Special Weather Statement issued May 06 at 8:08PM CDT by NWS</title>
    <link href="http://alerts.weather.gov/cap/wwacapget.php?x=TX124EFFB832F0.SpecialWeatherStatement.124EFFB84164TX.LUBSPSLUB.ac20a1425c958f66dc159baea2f9e672"/>
    <summary>...SIGNIFICANT WEATHER ADVISORY FOR COCHRAN AND BAILEY COUNTIES... AT 808 PM CDT...NATIONAL WEATHER SERVICE DOPPLER RADAR INDICATED A STRONG THUNDERSTORM 30 MILES NORTHWEST OF MORTON...MOVING SOUTHEAST AT 25 MPH. NICKEL SIZE HAIL...WINDS SPEEDS UP TO 40 MPH...CONTINUOUS CLOUD TO GROUND LIGHTNING...AND BRIEF MODERATE DOWNPOURS ARE POSSIBLE WITH</summary>
    <cap:event>Special Weather Statement</cap:event>
    <cap:effective>2013-05-06T20:08:00-05:00</cap:effective>
    <cap:expires>2013-05-06T20:45:00-05: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>Minor</cap:severity>
    <cap:certainty>Observed</cap:certainty>
    <cap:areaDesc>Bailey; Cochran</cap:areaDesc>
    <cap:polygon>34.19,-103.04 34.19,-103.03 33.98,-102.61 33.71,-102.61 33.63,-102.75 33.64,-103.05 34.19,-103.04</cap:polygon>
    <cap:geocode>
        <valueName>FIPS6</valueName>
        <value>048017 048079</value>
        <valueName>UGC</valueName>

        <value>TXZ027 TXZ033</value>
    </cap:geocode>
    <cap:parameter>
        <valueName>VTEC</valueName>
        <value>
        </value>
    </cap:parameter>
</entry>

我正在使用 simpleXML,并且我设置了一个简单的小测试脚本,它非常适合解析常规元素。我无法为我的狄更斯找到或找到一种方法来解析带有名称空间的元素。

这是一个小示例测试脚本,其中包含我正在使用的代码,非常适合解析简单元素。如何使用它来解析命名空间?我尝试过的一切都不起作用。我需要它能够创建变量,以便能够将它们嵌入到 html 中以获得样式。

<?php 

$html = "";  

// Get the XML Feed
$data = "http://alerts.weather.gov/cap/tx.php?x=1";


// load the xml into the object
$xml = simplexml_load_file($data);

for ($i = 0; $i < 10; $i++)
    $title = $xml->entry[$i]->title;
    $summary = $xml->entry[$i]->summary;

    $html .= "<p><strong>$title</strong></p><p>$summary</p><hr/>";



 echo $html; 
?> 

这可以很好地解析常规元素,但是那些在条目父项下带有 cap: 命名空间的元素呢?

<?php
ini_set('display_errors','1');

$html = "";
$data = "http://alerts.weather.gov/cap/tx.php?x=1";
$entries = simplexml_load_file($data);
if(count($entries)):
    //Registering NameSpace
    $entries->registerXPathNamespace('prefix', 'http://www.w3.org/2005/Atom');
    $result = $entries->xpath("//prefix:entry");
    //echo count($asin);
    //echo "<pre>";print_r($asin);
    foreach ($result as $entry):
        $title = $entry->title;
        $summary = $entry->summary;

        $html .= "<p><strong>$title</strong></p><p>$summary</p>$event<hr/>";

    endforeach;
endif;

echo $html;

?>

任何帮助将不胜感激。

-谢谢

【问题讨论】:

【参考方案1】:

我给出了相同类型的答案here - solution to your question

你只需要注册 Namespace 就可以正常使用 simplexml_load_file 和 XPath

<?php
$data = "http://alerts.weather.gov/cap/tx.php?x=1";
$entries = file_get_contents($data);
$entries = new SimpleXmlElement($entries);
if(count($entries)):
    //echo "<pre>";print_r($entries);die;
    //alternate way other than registring NameSpace
    //$asin = $asins->xpath("//*[local-name() = 'ASIN']");

    $entries->registerXPathNamespace('prefix', 'http://www.w3.org/2005/Atom');
    $result = $entries->xpath("//prefix:entry");
    //echo count($asin);
    //echo "<pre>";print_r($result);die;
    foreach ($result as $entry):
        //echo "<pre>";print_r($entry);die;
        $dc = $entry->children('urn:oasis:names:tc:emergency:cap:1.1');
        echo $dc->event."<br/>";
        echo $dc->effective."<br/>";
        echo "<hr>";
    endforeach;
endif;

就是这样。

【讨论】:

这些是常规元素。我解析这些没有问题。我遇到的问题是条目父项下的 CAP 命名空间。 IE。 , , , ...请看我在底部修改过的帖子。我还需要这些来生成没有回显的变量,以便进行样式设置。 感谢您让我找到正确的方向。我现在把所有东西都整理好了。对于命名空间元素,我只需要添加 $event = $entry->children("cap", true)->event; 更多 find here for details 我在更新的代码中使用。 现在不工作【参考方案2】:

这里有一个替代解决方案:

<?php
$xml = <<<XML
<?xml version = '1.0' encoding = 'UTF-8' standalone = 'yes'?>
<?xml-stylesheet href='http://alerts.weather.gov/cap/capatom.xsl' type='text/xsl'?>

<!--
This atom/xml feed is an index to active advisories, watches and warnings 
issued by the National Weather Service.  This index file is not the complete 
Common Alerting Protocol (CAP) alert message.  To obtain the complete CAP 
alert, please follow the links for each entry in this index.  Also note the 
CAP message uses a style sheet to convey the information in a human readable 
format.  Please view the source of the CAP message to see the complete data 
set.  Not all information in the CAP message is contained in this index of 
active alerts.
-->

<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, 07 May 2013 04:14:00 GMT -->

<id>http://alerts.weather.gov/cap/tx.atom</id>
<logo>http://alerts.weather.gov/images/xml_logo.gif</logo>
<generator>NWS CAP Server</generator>
<updated>2013-05-06T23:14:00-05:00</updated>
<author>
    <name>w-nws.webmaster@noaa.gov</name>
</author>
<title>Current Watches, Warnings and Advisories for Texas Issued by the National Weather Service</title>
<link href='http://alerts.weather.gov/cap/tx.atom'/>

<entry>
    <id>http://alerts.weather.gov/cap/wwacapget.php?x=TX124EFFB8AA78.FireWeatherWatch.124EFFD70270TX.EPZRFWEPZ.1716207877d94d15d43d410892b9f175</id>
    <updated>2013-05-06T23:14:00-05:00</updated>
    <published>2013-05-06T23:14:00-05:00</published>
    <author>
        <name>w-nws.webmaster@noaa.gov</name>
    </author>
    <title>Fire Weather Watch issued May 06 at 11:14PM CDT until May 08 at 10:00PM CDT by NWS</title>
    <link href="http://alerts.weather.gov/cap/wwacapget.php?x=TX124EFFB8AA78.FireWeatherWatch.124EFFD70270TX.EPZRFWEPZ.1716207877d94d15d43d410892b9f175"/>
    <summary>...CRITICAL FIRE CONDITIONS EXPECTED WEDNESDAY ACROSS FAR WEST TEXAS AND THE SOUTHWEST NEW MEXICO LOWLANDS... .WINDS ALOFT WILL STRENGTHEN OVER THE REGION EARLY THIS WEEK...AHEAD OF AN UPPER LEVEL TROUGH FORECAST TO MOVE THROUGH NEW MEXICO AND TEXAS ON WEDNESDAY. SURFACE LOW PRESSURE WILL ALSO DEVELOP TO OUR EAST AS THE TROUGH APPROACHES. THIS COMBINATION WILL RESULT</summary>
    <cap:event>Fire Weather Watch</cap:event>
    <cap:effective>2013-05-06T23:14:00-05:00</cap:effective>
    <cap:expires>2013-05-08T22:00:00-05:00</cap:expires>
    <cap:status>Actual</cap:status>
    <cap:msgType>Alert</cap:msgType>
    <cap:category>Met</cap:category>
    <cap:urgency>Future</cap:urgency>
    <cap:severity>Moderate</cap:severity>
    <cap:certainty>Possible</cap:certainty>
    <cap:areaDesc>El Paso; Hudspeth</cap:areaDesc>
    <cap:polygon></cap:polygon>
    <cap:geocode>
        <valueName>FIPS6</valueName>
        <value>048141 048229</value>
        <valueName>UGC</valueName>
        <value>TXZ055 TXZ056</value>
    </cap:geocode>
    <cap:parameter>
        <valueName>VTEC</valueName>
        <value>/O.NEW.KEPZ.FW.A.0018.130508T1900Z-130509T0300Z/</value>
    </cap:parameter>
</entry>

<entry>
    <id>http://alerts.weather.gov/cap/wwacapget.php?x=TX124EFFABB2F0.AirQualityAlert.124EFFC750DCTX.HGXAQAHGX.7f2cf548a67d403f0541492b2804d621</id>
    <updated>2013-05-06T14:16:00-05:00</updated>
    <published>2013-05-06T14:16:00-05:00</published>
    <author>
        <name>w-nws.webmaster@noaa.gov</name>
    </author>
    <title>Air Quality Alert issued May 06 at 2:16PM CDT by NWS</title>
    <link href="http://alerts.weather.gov/cap/wwacapget.php?x=TX124EFFABB2F0.AirQualityAlert.124EFFC750DCTX.HGXAQAHGX.7f2cf548a67d403f0541492b2804d621"/>
    <summary>...OZONE ACTION DAY FOR TUESDAY... THE TEXAS COMMISSION ON ENVIRONMENTAL QUALITY (TCEQ)...HAS ISSUED AN OZONE ACTION DAY FOR THE HOUSTON...GALVESTON...AND BRAZORIA AREAS FOR TUESDAY...MAY 7 2013. ATMOSPHERIC CONDITIONS ARE EXPECTED TO BE FAVORABLE FOR PRODUCING HIGH LEVELS OF OZONE POLLUTION IN THE HOUSTON...GALVESTON AND</summary>
    <cap:event>Air Quality Alert</cap:event>
    <cap:effective>2013-05-06T14:16:00-05:00</cap:effective>
    <cap:expires>2013-05-07T19:15:00-05:00</cap:expires>
    <cap:status>Actual</cap:status>
    <cap:msgType>Alert</cap:msgType>
    <cap:category>Met</cap:category>
    <cap:urgency>Unknown</cap:urgency>
    <cap:severity>Unknown</cap:severity>
    <cap:certainty>Unknown</cap:certainty>
    <cap:areaDesc>Brazoria; Galveston; Harris</cap:areaDesc>
    <cap:polygon></cap:polygon>
    <cap:geocode>
        <valueName>FIPS6</valueName>
        <value>048039 048167 048201</value>
        <valueName>UGC</valueName>
        <value>TXZ213 TXZ237 TXZ238</value>
    </cap:geocode>
    <cap:parameter>
        <valueName>VTEC</valueName>
        <value></value>
    </cap:parameter>
</entry>
</feed>
XML;

$sxe       = new SimpleXMLElement($xml);
$capFields = $sxe->entry->children('cap', true);

echo "Event: " . (string) $capFields->event . "\n";
echo "Effective: " . (string) $capFields->effective . "\n";
echo "Expires: " . (string) $capFields->expires . "\n";
echo "Severity: " . (string) $capFields->severity . "\n";

输出:

Event: Fire Weather Watch
Effective: 2013-05-06T23:14:00-05:00
Expires: 2013-05-08T22:00:00-05:00
Severity: Moderate

【讨论】:

关键点是children('cap', true)。直接使用$xml-&gt;event$xml-&gt;'cap:event' 似乎不受支持。

以上是关于使用 php SimpleXML 解析 XML 命名空间的主要内容,如果未能解决你的问题,请参考以下文章

PHP - 使用 simplexml_load_string 解析 XML - 使用 CDATA 获取空值? [复制]

simpleXML技术解析xml文件(php)

php使用SimpleXML解析xml文档将其转化为数组

simpleXML技术解析xml文件(php)

PHP中用simpleXML解析XML文档,为啥总出错?

PHP SimpleXML解析具有多个属性的元素