XML 2 mySQL 致命错误:调用成员函数 item()



实际我试图将XML导入MySQL

for ($i=0; $i < $itemCount; $i++) {
$title = $xmlObject->item($i)->getElementsByTagName('title')->item(0)->childNodes->item(0)->nodeValue;
$link  = $xmlObject->item($i)->getElementsByTagName('link')->item(0)->childNodes->item(0)->nodeValue;
$image_link  = $xmlObject->item($i)->getElementsByTagName('image_link')->item(0)->childNodes->item(0)->nodeValue;
$price  = $xmlObject->item($i)->getElementsByTagName('price')->item(0)->childNodes->item(0)->nodeValue;
$brand  = $xmlObject->item($i)->getElementsByTagName('brand')->item(0)->childNodes->item(0)->nodeValue;
$availability = $xmlObject->item($i)->getElementsByTagName('availability')->item(0)->childNodes->item(0)->nodeValue;  
$id = $xmlObject->item($i)->getElementsByTagName('id')->item(0)->childNodes->item(0)->nodeValue;  
$product_type = $xmlObject->item($i)->getElementsByTagName('product_type')->item(0)->childNodes->item(0)->nodeValue;  
$description = $xmlObject->item($i)->getElementsByTagName('description')->item(0)->childNodes->item(0)->nodeValue;  
$sale_price = $xmlObject->item($i)->getElementsByTagName('sale_price')->item(0)->childNodes->item(0)->nodeValue;  

添加最后一个对象Saleprice后,我收到错误消息

致命错误:在 null 中调用成员函数 item()

我认为问题是并非每件商品都设置了"销售价格"值

但是我该如何解决 - 如果设置了该值>则该值将导入MySQL

提前致谢


XML 示例

<item>
<g:id>4</g:id>
<title>sadsadsdsadsadsadsadasd</title>
<description>dddddddd</description>
<g:product_type>aaaaaaaaa</g:product_type>
<link>https://www.xyz.de</link>
<g:image_link>https://www.xyz.de/600x600.jpg</g:image_link>
<g:condition>new</g:condition>
<g:availability>out of stock</g:availability>
<g:price>5,95</g:price>
<g:sale_price>4,99</g:sale_price>
<g:brand>asdasdsddsn</g:brand>
<g:gtin>137</g:gtin>
<g:mpn></g:mpn>
<g:shipping>
<g:country>DE</g:country>
<g:service>Standard</g:service>
<g:price>7,99</g:price>
</g:shipping>
<pubDate>Fri, 07 Dec 2018 12:10:02 CET</pubDate></item>

您将访问列表的第一个节点,而不检查列表是否有节点。

$sale_price =  
$xmlObject // DOM node list
->item($i) // DOM node at index $i
->getElementsByTagName('sale_price') // list of'sale_price' descendant elements
->item(0) // first node in list - NULL if list is empty
->childNodes // child nodes list - this includes text nodes
->item(0)  // first node in list - NULL if list is empty
->nodeValue; // node content

如果此处没有sale_price元素(在其中一个上下文节点中),则会发生错误。因此,如果使用 DOM 方法,则必须检查每个级别以避免这种情况。

或者您开始使用 XPath:

$xml = <<<'XML'
<products>
<product>
<title>With sale_price</title>
<sale_price>42.00</sale_price>
</product>
<product>
<title>Without sale_price</title>
</product>
</products>
XML;
$document = new DOMDocument();
$document->loadXML($xml);
$xpath = new DOMXpath($document);
foreach($xpath->evaluate('//product') as $product) {
echo $xpath->evaluate('string(title)', $product), ': ';
echo $xpath->evaluate('string(sale_price)', $product), "n";
}

输出:

With sale_price: 42.00 
Without sale_price:

如果在表达式中强制转换节点列表,DOMXpath::evaluate()可以返回具有位置路径表达式(如//product和标量值)的节点列表。string(title)会将所有title子节点提取到一个列表中,并将第一个节点转换为字符串(返回其文本内容),如果找不到节点,它将返回一个空字符串。

有几种方法可以解决这个问题,你目前的做法可以缩短,这样就不会有那么多代码。 使用 sale_price,这将获取元素列表,如果没有元素,则默认为 0...

for ($i=0; $i < $itemCount; $i++) {
$title = $xmlObject->item($i)->getElementsByTagName('title')->item(0)->nodeValue;
$link  = $xmlObject->item($i)->getElementsByTagName('link')->item(0)->nodeValue;
$image_link  = $xmlObject->item($i)->getElementsByTagName('image_link')->item(0)->nodeValue;
$price  = $xmlObject->item($i)->getElementsByTagName('price')->item(0)->nodeValue;
$brand  = $xmlObject->item($i)->getElementsByTagName('brand')->item(0)->nodeValue;
$availability = $xmlObject->item($i)->getElementsByTagName('availability')->item(0)->nodeValue;
$id = $xmlObject->item($i)->getElementsByTagName('id')->item(0)->nodeValue;
$product_type = $xmlObject->item($i)->getElementsByTagName('product_type')->item(0)->nodeValue;
$description = $xmlObject->item($i)->getElementsByTagName('description')->item(0)->nodeValue;
$sale_price = $xmlObject->item($i)->getElementsByTagName('sale_price');
$sale_price =  ( count($sale_price) > 0 )? $sale_price->item(0)->nodeValue : 0;
$sql   = "Insert into xxxxxxxxx (title, link, image_link, price, brand, availability, id, product_type, description, sale_price) VALUE ('$title', '$link', '$image_link', '$price', '$brand', '$availability', '$id', '$product_type', '$description', '$sale_price')";
echo $sql.PHP_EOL;
}

或者你可以切换到SimpleXML,这是更少的代码。 在这里,您可以使用 PHP 的isset()来检查是否有值,如果没有,则设置为 0。 在 PHP 7 中,你也可以使用空合并 (??) 来做同样的事情...

$xml = simplexml_load_file("data.xml");   // Load from a file
// $xml = simplexml_load_string($xmlData);   // Load from a string
foreach ( $xml->item as $item ) {
$g = $item->children("g", true);
$title = (string)$item->title;
$link  = (string)$item->link;
$image_link  = (string)$g->image_link;
$price  = (string)$g->price;
$brand  = (string)$g->brand;
$availability = (string)$g->availability;
$id = (string)$g->id;
$product_type = (string)$g->product_type;
$description = (string)$item->description;
$sale_price = (string)(isset($g->sale_price) ?$g->sale_price: 0);
// $sale_price = (string)($g->sale_price ?? 0);   // PHP 7+
$sql   = "Insert into xxxxxxxxx (title, link, image_link, price, brand, availability, id, product_type, description, sale_price) VALUE ('$title', '$link', '$image_link', '$price', '$brand', '$availability', '$id', '$product_type', '$description', '$sale_price')";
echo $sql.PHP_EOL;
}

SimpleXML中唯一的复杂之处在于它必须考虑命名空间,因此任何带有g前缀(例如id)的元素都需要从$g变量中读取,该变量是节点上所有g前缀的元素。

最新更新