使用PHP从具有未知字段的XML中提取数据

时间:2018-12-31 00:18:10

标签: php xml parsing

我的Feed中有几种产品,但是字段未知。我想使用PHP从文件中显示“树状结构”。

XML如下所示:

<products>
  <product id="1">
    <title>Title of product 1</title>
    <weight measure="kg">4000</weight>
    <specs>
       <spec name="spec1">
       <value>value spec 1</value>
       <spec name="spec2">
       <value>value spec 2</value>
    </specs>
  </product>
  <product id="2">
    <title>Title of product 2</title>
    <weight measure="kg">10000</weight>
    <specs>
       <spec name="spec1">
       <value>value spec 1</value>
       <spec name="spec2">
       <value>value spec 2</value>
       <spec name="spec3">
       <value>value spec 3</value>
    </specs>
  </product>
</products>

我希望我的PHP显示类似这样的内容,以便可以在数据库中插入以下值:

Product: 1
title: Title of product 1
weight: 4000
spec1: value spec 1
spec2: value spec 2

Product: 2
title: Title of product 2
weight: 10000
spec1: value spec 1
spec2: value spec 2
spec3: value spec 3

如上所述,提要每次都不同,具有不同的字段。那让我更难了。

$xml = simplexml_load_file($feedURL);
foreach($xml->product as $products) {
    echo '>.'.$products[ID].'<br>';
    foreach($products->children() as $properties){
        echo $properties[name].': '.$properties->value.'<br>';
        foreach($properties->children() as $aspects){
            echo '--->'.$aspects[name].': '.$aspects->value.'<br>';
        }
    }
}

目前不起作用。我该如何解决?

2 个答案:

答案 0 :(得分:1)

问题是我已经复制了您的XML文件,但这并不是真的有效。

http://www.xmlvalidation.com/index.php?id=1&L=2

您可以使用验证器,并且在加载文件时,PHP中会出现一些错误,表明XML文件无效。而且,当您查看XML时,“规格”并不是真正正确的。

<spec name="spec1">
<value>value spec 1</value>

<spec name="spec2">
<value>value spec 2</value>

<spec name="spec3">
<value>value spec 3</value>

您的“ spec”标记未关闭,这会导致一些错误。您必须关闭spec标签或将其作为单个标签。

<spec name="spec2">
    <value>value spec 2</value>
</spec>

您应该先解决问题。然后,您应该能够获得正确的值。否则,当您启用php错误时,您会看到xml无效的错误。

答案 1 :(得分:1)

首先,您的XML存在问题,因为您的<spec>标签未正确关闭,因此simplexml_load_string实际上不会加载XML。您可以使用preg_match例如

来解决此问题
$xmlstr = file_get_contents($feedURL);
$xml = simplexml_load_string(preg_replace('/(<spec [^>]+)>/', '$1 />', $xmlstr));

这将转换为:

<spec name="spec1">

<spec name="spec1" />

然后,您的代码还有其他问题。

  1. 您正在使用未加引号的字符串,例如IDname
  2. 要获取SimpleXMLElement的名称,请使用$element->getName(),而不要使用$element['name']
  3. 要获取SimpleXMLElement的值,只需将其转换为适当的类型,例如(string)$element不是$element->value

启用错误报告功能会在您提出问题之前 出现很多此类问题。对代码进行所有这些更正可以得到以下结果:

foreach($xml->product as $products) {
    echo 'Product: '.$products['id']."\n";
    foreach($products->children() as $properties){
        if (!count($properties->children())) echo $properties->getName().': '.(string)$properties."\n";
        foreach($properties->children() as $aspects){
            if ($aspects->getName() == 'spec')
                echo $aspects['name'].': ';
            else
                echo (string)$aspects . "\n";
        }
    }
}

哪个给出以下输出:

Product: 1 
title: Title of product 1 
weight: 4000 
spec1: value spec 1 
spec2: value spec 2 
Product: 2 
title: Title of product 2 
weight: 10000 
spec1: value spec 1 
spec2: value spec 2 
spec3: value spec 3

Demo on 3v4l.org