2013-06-28 53 views
0

尝试XPath查询新创建的节点时,总是收到消息PHP Notice: Trying to get property of non-object in ...更改DOM后PHP XPath查询错误

我的XML文件是这样的:

<products xmlns='http://example.com/products'> 
    <product id='1'> 
     <name>Product name</name> 
    </product> 
</products> 

我的PHP文件基本上是适用的XPath查询,以获得现有<product>并为其<name>第二查询。这工作正常。

然后,我将一个新的<product>与孩子<name>插入DOM根元素,并尝试对新创建的元素进行第二次查询。获取属性可以正常工作,但第二个查询应该得到第一个子项<name>的值,并且PHP通知Trying to get property of non-object in ...失败。

$xmlFile = __DIR__ . '/products.xml'; 

$xml = new DOMDocument(); 
$xml->load($xmlFile); 
$xml->formatOutput = true; 

$xpath = new DOMXPath($xml); 
$xpath->registerNamespace('p', $xml->lookupNamespaceUri($xml->namespaceURI)); 

/* 
* query the first product's ID and name 
*/ 

$product1 = Product::$xpath->query("//p:product[@id=1]")->item(0); 

$product1Id = $product1->attributes->getNamedItem('id')->nodeValue; 
// => "1" 
$product1Name = $xpath->query("p:name", $product1)->item(0)->nodeValue; 
// => "Product name" 

/* 
* create the second product 
*/ 

$product2Node = $xml->createElement('product'); 
$product2Node->setAttribute('id', '2'); 

$product2NameNode = $xml->createElement('name', 'Test'); 
$product2Node->appendChild($product2NameNode); 

$product2 = $xml->documentElement->appendChild($product2Node); 

/* 
* query the second product's ID and name 
*/ 

$product2Id = $product2->attributes->getNamedItem('id')->nodeValue; 
// => "2" 
$product2Name = $xpath->query("p:name", $product2)->item(0)->nodeValue; 
// => PHP Notice: Trying to get property of non-object in ... 

$xml->save($xmlFile); 

运行PHP文件之后,XML看起来是正确的:

<products xmlns='http://example.com/products'> 
    <product id='1'> 
     <name>Product name</name> 
    </product> 
    <product id='2'> 
     <name>Test</name> 
    </product> 
</products> 

我真的停留在此,我试图查询之前保存XML,保存后重新加载XML,重建中的XPath对象等

回答

1

我相信你需要使用createElementNS功能(http://php.net/manual/en/domdocument.createelementns.php,你可能还需要检查setAttributeNS - http://www.php.net/manual/en/domelement.setattributens.php),而不是createElement为了明确表明,这些元素属于http://example.com/products命名空间。

$product2Node = $xml->createElementNS('http://example.com/products', 'product'); 
$product2Node->setAttribute('id', '2'); 

$product2NameNode = $xml->createElementNS('http://example.com/products', 'name', 'Test'); 
$product2Node->appendChild($product2NameNode); 

(这是一个有点令人惊讶的是保存后重新加载XML并没有解决这个问题,但没有看到那个试图做到这一点很难知道什么可能出现了问题重装的代码。)

+0

它的工作原理, 谢谢! :) – David