SimpleXMLElement Access elements with namespace?

2019-01-20 17:53发布

I have the following XML:

<ns1:getBannerLinksResponse xmlns:ns1="http://endpoint.website.com/">
    <ns1:return>
        <ns1:campaignID>0</ns1:campaignID>
        <ns1:categoryID>200230455</ns1:categoryID>
        <ns1:categoryName>Promotion</ns1:categoryName>
        <ns1:linkID>10001599</ns1:linkID>
        <ns1:linkName>KFL-20% off No Min</ns1:linkName>
        <ns1:mid>3071</ns1:mid>
        <ns1:nid>1</ns1:nid>
        <ns1:clickURL>
            http://someurl
        </ns1:clickURL>
        <ns1:endDate>Oct 15, 2012</ns1:endDate>
        <ns1:height>250</ns1:height>
        <ns1:iconURL>
            http://someurl
        </ns1:iconURL>
        <ns1:imgURL>
            http://someurl
        </ns1:imgURL>
        <ns1:landURL>
            http://someurl
        </ns1:landURL>
        <ns1:serverType>22</ns1:serverType>
        <ns1:showURL>
            http://someurl
        </ns1:showURL>
        <ns1:size>13</ns1:size>
        <ns1:startDate>Oct 14, 2012</ns1:startDate>
        <ns1:width>300</ns1:width>
    </ns1:return>
</ns1:getBannerLinksResponse>

I tried the following with no luck:

$data = new SimpleXMLElement($xml);
$data->registerXPathNamespace('ns1','http://endpoint.website.com/');
foreach($data->xpath('//ns1:return') as $banner)
{
  $banner->registerXPathNamespace('ns1','http://endpoint.website.com/');
  var_dump($banner);
}

2条回答
Luminary・发光体
2楼-- · 2019-01-20 18:17

You need to use the ->children() method. If you avoid XPath and just use the SimpleXML operators, your code will end up much simpler.

Namespaced elements are also one of many things not visible when using standard PHP debug functions to debug the rather magical SimpleXML objects. (The below uses [my simplexml_dump() function instead.)

$data = new SimpleXMLElement($xml);
$banner = $data->children('ns1', true)->return; 
// Or to avoid relying on the 'ns1' alias: ->children('http://endpoint.website.com/', false);
simplexml_dump($banner);

Note that the 'ns1' namespace remains selected until another ->children() call:

// Remember to cast to string if you want the content of an element or attribute
var_dump( (string)$banner->linkName );

If <return> can occur multiple times, this obviously becomes:

foreach ( $data->children('ns1', true)->return as $banner )
{
    simplexml_dump($banner);
}
查看更多
仙女界的扛把子
3楼-- · 2019-01-20 18:28

All you need is

$data = new SimpleXMLElement($xml);
$data->registerXPathNamespace('ns1','http://endpoint.websitecom/');
$part = $data->xpath("//ns1:return");
var_dump($part[0]->children("ns1",true));

Output

object(SimpleXMLElement)[3]
  public 'campaignID' => string '0' (length=1)
  public 'categoryID' => string '200230455' (length=9)
  public 'categoryName' => string 'Promotion' (length=9)
  public 'linkID' => string '10001599' (length=8)
  public 'linkName' => string 'KFL-20% off No Min' (length=18)
  public 'mid' => string '3071' (length=4)
  public 'nid' => string '1' (length=1)
  public 'clickURL' => string '
            http://someurl
        ' (length=36)
  public 'endDate' => string 'Oct 15, 2012' (length=12)
  public 'height' => string '250' (length=3)
  public 'iconURL' => string '
            http://someurl
        ' (length=36)
  public 'imgURL' => string '
            http://someurl
        ' (length=36)
  public 'landURL' => string '
            http://someurl
        ' (length=36)
  public 'serverType' => string '22' (length=2)
  public 'showURL' => string '
            http://someurl
        ' (length=36)
  public 'size' => string '13' (length=2)
  public 'startDate' => string 'Oct 14, 2012' (length=12)
  public 'width' => string '300' (length=3)
查看更多
登录 后发表回答