【问题标题】:SimpleXMLElement: asXML() "on a non-object" that really is an objectSimpleXMLElement: asXML() “在一个非对象上”,它确实是一个对象
【发布时间】:2014-03-09 21:27:43
【问题描述】:

我正在使用 PHP 中的 SimpleXMLElement 解析 SVG 文件。 SVG 文件是在 Adob​​e Illustrator 中精心构建的,遵循我试图剖析的图层格式。

考虑这段代码:

// 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
    }
  }
}

当我在$floorsvg 上执行var_dump 时,它声明它是一个 SimpleXMLElement 对象:

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

但是,当我在对象上运行 asXML() 时,我会看到以下 PHP 错误:

PHP 致命错误:在非对象上调用成员函数 asXML()

我不确定为什么asXML() 会失败,因为它是一个对象。谁能解释为什么会出现这个问题以及我可能会尝试解决什么问题?

编辑:在上面添加echo $normal->asXML(); 会导致相同的错误。似乎xpath 导致对象以某种方式出现格式错误。

编辑 2: 可以在此处看到正在解析的 SVG 文件:http://pastebin.com/zK1yRFA7

【问题讨论】:

  • 你能把你的 SVG 文件贴在某个地方吗?
  • @SeanBright 当然,我已经将我的帖子编辑到了 SVG 的 PasteBin 转储中。
  • 所以我必须做出我在(现已删除)答案中建议的更改以避免语法错误,但是一旦我这样做了,您的代码就可以正常工作了。
  • 我不确定它对你有什么作用。我在键盘上重新创建了这个问题:codepad.viper-7.com/sWMKIP

标签: php xpath svg simplexml


【解决方案1】:

有几个问题。您的代码假定:

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

将返回一个至少包含 1 个元素的数组。 <g id="Second_Floor"> 元素不包含任何将与该 XPath 表达式匹配的子元素,因此尝试访问空数组的元素 0 会出现您所看到的错误。

添加一个简单的保护表达式:

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

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

会解决的。其次,您在这一行中有一些放错位置的括号:

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

应该是:

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

似乎只是一个简单的错字,似乎不会以某种方式影响这个特定脚本的结果。

【讨论】:

  • 不,我试过了。我还尝试将其进一步向下移动$floorsvg[0]->asXML(); 没有骰子。
  • OK...第三次是魅力。 (我希望)
  • 你发现了我的忽视!我忘记了“Base”的id 在其他情况下略有变化。 (例如,“Second_Floor”上的“Base_1_”)。我修改了我的 xpath 看起来像 svg:g[starts-with(@id, "Base")] 这解决了这个问题。感谢您的工作(以及发现我的计数错误)。
猜你喜欢
  • 2023-03-25
  • 1970-01-01
  • 2019-02-28
  • 2021-01-11
  • 1970-01-01
  • 1970-01-01
  • 2019-12-19
  • 1970-01-01
  • 2018-12-13
相关资源
最近更新 更多