【问题标题】:XML 2 mySQL Fatal error: Call to a member function item()XML 2 mySQL 致命错误:调用成员函数 item()
【发布时间】:2018-12-13 00:54:57
【问题描述】:

实际上我正在尝试将 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 后,我收到错误消息

致命错误:调用成员函数 item() on null in

我认为问题是不是在每个项目中都设置了“销售价格”的值

但我该如何解决 - 如果设置了值 > 值会被导入 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>

【问题讨论】:

  • 您能否添加一个您正在处理的 XML 示例。
  • @NigelRen of course

标签: php mysql xml import tags


【解决方案1】:

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

$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 子节点提取到一个列表中,并将第一个节点转换为一个字符串(返回其文本内容),如果找不到节点,它将返回一个空字符串。

【讨论】:

    【解决方案2】:

    有几种方法可以解决这个问题,您当前的做法可以缩短,这样就没有太多代码了。使用 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 中,你也可以使用 null coalesce (??) 来做同样的事情......

    $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 前缀的元素.

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-22
      • 2012-09-29
      • 2014-02-05
      • 2014-04-29
      • 2015-09-14
      • 2014-10-07
      • 1970-01-01
      相关资源
      最近更新 更多