【问题标题】:Parse xml with linked multi-values使用链接的多值解析 xml
【发布时间】:2015-05-23 16:28:28
【问题描述】:

我有类似的xml:

<?xml version="1.0" encoding="UTF-8"?>
<shop>
  <categories>
    <category id="310" parent_id="305" title="PHILIPS"/>
     <category id="305" parent_id="233" title="LED TV"/>
     <category id="233" parent_id="0" title="Television" title_ru="cat1 ru" title_en="cat1 en"/>

     <category id="525" parent_id="435" title="Manufacturer"/>
     <category id="396" parent_id="0" title="Parrent categgory"/>
     <category id="435" parent_id="396" title="Sub category"/>
  </categories>
  <products>
    <product id="807" category_id="525" code="1002" price="3.95" count="99" name="Product 1"/>
    <product id="2002" category_id="525" code="EFG 90750X" price="99" count="0" name="Product 2"/>
    <product id="2691" category_id="525" code="L 87695WD" price="99" count="1" name="Product 3"/>
    <product id="2909" category_id="525" code="ZEI 6240FBA" price="99" count="0" name="Product 4"/>
    <product id="3532" category_id="525" code="HK 654400XB" price="99" count="0" name="Product 5"/>
<product id="4150" category_id="310" code="24PHH4109/88" price="99" is_featured="1" count="&gt;10" name="Product 6"/>
    <product id="4378" category_id="310" code="22PFK4209/12" price="99" is_featured="1" count="&gt;10" name="Product 7"/>
    <product id="4065" category_id="310" code="22PFH4109/88" price="99" is_featured="1" count="&gt;10" name="Product 8"/>
    <product id="4080" category_id="310" code="20PHH4109/88" price="99" is_featured="1" count="&gt;10" name="Product 9"/>
  </products>
</shop>

我可以通过代码解析“产品”:

$url = "code.xml";
$xml = simplexml_load_file($url);

foreach($xml->products->product as $product) {

echo 
'"L_'.$product[0]['code'].'_'.$product[0]['id'].
'"^"'.$product[0]['name'].
'"^"'.$product[0]['category_id'].
'"^"0.01"^^^^^'
.'"'.$product[0]['code'].'"'.
"\n";
}

但在这种情况下,我没有得到“制造商”、“父类别”和“子类别”值,如何解析?

【问题讨论】:

    标签: php xml xml-parsing export-to-csv


    【解决方案1】:

    一种方法是对您的 XML 对象使用 XPath 查询:

    $url = "code.xml";
    $xml = simplexml_load_file($url);
    
    foreach ($xml->products->product as $product) {
        // Get categories
        $categoryId           = $product['category_id'];
        list($category)       = $xml->xpath("//category[@id=$categoryId]");
    
        $subCategoryId        = $category['parent_id'];
        list($subCategory)    = $xml->xpath("//category[@id=$subCategoryId]");
    
        $parentCategoryId     = $subCategory['parent_id'];
        list($parentCategory) = $xml->xpath("//category[@id=$parentCategoryId]");
    
        // Show categories
        echo "Category:        ", $category['title'], PHP_EOL;
        echo "Sub category:    ", $subCategory['title'], PHP_EOL;
        echo "Parent category: ", $parentCategory['title'], PHP_EOL;
    
        // Same as before
        echo
            '"L_'.$product[0]['code'].'_'.$product[0]['id'].
            '"^"'.$product[0]['name'].
            '"^"'.$product[0]['category_id'].
            '"^"0.01"^^^^^'
            .'"'.$product[0]['code'].'"'.
            "\n";
    }
    

    输出:

    Category:        Manufacturer
    Sub category:    Sub category
    Parent category: Parrent categgory
    "L_1002_807"^"Product 1"^"525"^"0.01"^^^^^"1002"
    Category:        Manufacturer
    Sub category:    Sub category
    Parent category: Parrent categgory
    "L_EFG 90750X_2002"^"Product 2"^"525"^"0.01"^^^^^"EFG 90750X"
    ...
    Category:        PHILIPS
    Sub category:    LED TV
    Parent category: Television
    "L_20PHH4109/88_4080"^"Product 9"^"310"^"0.01"^^^^^"20PHH4109/88"
    

    【讨论】:

      【解决方案2】:

      XPath 是要走的路。但是您需要将任务分开。为“编号”变量调用相同的代码(或使用多个前缀,例如:subparent)是您应该使用循环的好兆头。

      在这种情况下,只要获得大于零的父 id,就会获取类别数据的循环。

      $dom = new DOMDocument();
      $dom->loadXml($xml);
      $xpath = new DOMXPath($dom);
      
      function getCategories($xpath, $id) {
        $result = [];
        do {
          $categories = $xpath->evaluate('/shop/categories/category[@id = "'.$id.'"]'); 
          if ($category = $categories->item(0)) {
            $result[$id] = [
              'id' => $id,
              'title' => $category->getAttribute('title')
            ];
            $id = $category->getAttribute('parent_id');
          } else {
            break;
          }
        } while ($id > 0);
        return $result;
      }
      
      $result = [];
      foreach ($xpath->evaluate('//product') as $product) {
        $result[] = [
          'name' => $product->getAttribute('name'),
          'categories' => getCategories($xpath, $product->getAttribute('category_id'))
        ];
      }
      var_dump($result);
      

      输出:

      array(9) {
        [0]=>
        array(2) {
          ["name"]=>
          string(9) "Product 1"
          ["categories"]=>
          array(3) {
            [525]=>
            array(2) {
              ["id"]=>
              string(3) "525"
              ["title"]=>
              string(12) "Manufacturer"
            }
            [435]=>
            array(2) {
              ["id"]=>
              string(3) "435"
              ["title"]=>
              string(12) "Sub category"
            }
            [396]=>
            array(2) {
              ["id"]=>
              string(3) "396"
              ["title"]=>
              string(17) "Parrent categgory"
            }
          }
        }
        [1]=>
        array(2) {
          ["name"]=>
          string(9) "Product 2"
          ["categories"]=>
          array(3) {
            [525]=>
            array(2) {
              ["id"]=>
              string(3) "525"
              ["title"]=>
              string(12) "Manufacturer"
            }
            ...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-28
        • 2018-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多