Michael Irigoyen
Michael Irigoyen

Reputation: 22947

SimpleXMLElement: asXML() "on a non-object" that really is an object

I am parsing a SVG file using SimpleXMLElement in PHP. The SVG file is carefully constructed in Adobe Illustrator follow a layer format that I am attempted to dissect.

Consider this code:

// Create an XML object out of the SVG
$svg = new SimpleXMLElement('floorplan.svg', null, true);

// Register the SVG namespace
$svg->registerXPathNamespace('svg', 'http://www.w3.org/2000/svg');

// Get the normal floorplan layer
$normal = $svg->xpath('svg:g[@id="Normal"]');

// If the normal layer has content, continue
if(count($normal) > 0) {
  // If there are floors, continue
  if(count($normal[0]->g > 0)) {
    // Loop through each floor
    foreach($normal[0]->g as $floor) {
      // Declare the namespace for the floor
      $floor->registerXPathNamespace('svg', 'http://www.w3.org/2000/svg');

      // Select the base floorplan
      $floorsvg = $floor->xpath('svg:g[@id="Base"]')[0];

      var_dump($floorsvg);
      echo $floorsvg->asXML();  // THIS CAUSES THE ERROR
    }
  }
}

When I do a var_dump on $floorsvg, it is declaring it is a SimpleXMLElement object:

object(SimpleXMLElement)[9]
  public '@attributes' => 
    array (size=1)
      'id' => string 'Base' (length=4)
  public 'g' => 
    array (size=859)
      0 => ...

However, when I run asXML() on the object, I am presented with the following PHP error:

PHP Fatal error: Call to a member function asXML() on a non-object

I'm uncertain why asXML() is failing, considering it is an object. Can anyone shed any light on why this problem is occurring and what I might try to remedy it?

EDIT: Adding an echo $normal->asXML(); up above results in the same error. It seems like xpath is causing the object to become malformed somehow.

EDIT 2: The SVG file being parsed can be seen here: http://pastebin.com/zK1yRFA7

Upvotes: 0

Views: 448

Answers (1)

Sean Bright
Sean Bright

Reputation: 120704

There are a few issues. Your code assumes that:

$floor->xpath('svg:g[@id="Base"]')

Will return an array with at least 1 element. The <g id="Second_Floor"> element does not contain any child elements that will be matched by that XPath expression, so trying to access element 0 of an empty array will give you the error you are seeing.

Adding a simple guard expression:

// Select the base floorplan
$floorsvg = $floor->xpath('svg:g[@id="Base"]')

if (count($floorsvg) > 0) {
    echo $floorsvg[0]->asXML();
}

Will resolve that. Secondly, you have some misplaced parentheses in this line:

if(count($normal[0]->g > 0)) {

It should be:

if(count($normal[0]->g) > 0) {

Appears to be just a simple typo and doesn't appear to affect the outcome of this particular script one way or another.

Upvotes: 1

Related Questions