【问题标题】:PHP parsing XML data and draw HTML TablePHP解析XML数据并绘制HTML表格
【发布时间】:2021-11-15 16:33:09
【问题描述】:

我有一个案例,我需要解析如下所示的“产品规范”XML 样式文档(数据):

    <Message>
    <EntityType>Document</EntityType>
    <ProductSETS>
      <Entity>
       <id>1</id>
       <Specification1>Human readable title 1</Specification1>
       <Specification2>Human readable title 2</Specification2>
       <Price>Product Price</Price>
       [...more elements of same row amount...]
      </Entity>
    
      <Entity>
       <id>100</id>
       <Specification1>Red</Specification1>
       <Specification2>Square</Specification2>
       <Price>8888</Price>
       [...more elements of same row amount...]
      </Entity>
    
      <Entity>
       <id>101</id>
       <Specification1>Blue</Specification1>
       <Specification2>Round</Specification2>
       <Price>9999</Price>
       [...more elements of same row amount...]
      </Entity>
    
    </ProductSETS>
    </Message>

简而言之,我需要在值得信赖的 PHP 的帮助下,打印一个包含 XML 数据的表格,例如:

_____________________________________________________________________
| ProductSET for ID 100                                             |
---------------------------------------------------------------------
| Human readable title 1                 |  Red                     |
| Human readable title 2                 |  Square                  |
| Product Price                          |  8888                    |
| Next element in human readable form    |  ID. 100 ELEMENT [...]   |
[   .... and loop until end of <Entity> <id>100</id>  ............. |
_____________________________________________________________________
| ProductSET for ID 101                                             |
---------------------------------------------------------------------
| Human readable title 1                 |  Blue                    |
| Human readable title 2                 |  Round                   |
| Product Price                          |  9999                    |
| Next element in human readable form    |  ID. 101 ELEMENT [...]   |
[   .... and loop until end of <Entity> <id>101</id>  ............. |
_____________________________________________________________________

请注意,xml 始终将第一个实体作为类似“标题”的条目,其中 1 用于映射产品规范标题的“人类可读”值 并在“标题”实体之后显示实际的产品规格值(颜色、尺寸、价格等)

问题是我需要两种方法来显示带有来自 XML 数据的值的 HTML 表格:

列出所有(没有实体为 1,但仍然使用它的值)

foreach ($feed->ProductSETS->Entity) :
if(ProductSETS->Entity->id != "1"){
  <tr><th><? echo ProductSETS->Entity->[1]->Specification1 ?>:</th>
<td><? echo ProductSETS->Entity->[100]->Title->Value ?> (Red)</td> </tr>
  <tr><th><? echo ProductSETS->Entity->[1]->Specification2 ?>:</th>
<td><? echo ProductSETS->Entity->[100]->Title->Value ?> (Square)</td> </tr>

  <tr><th><? echo ProductSETS->Entity->[1]->Specification1 ?>:</th>
<td><? echo ProductSETS->Entity->[101]->Title->Value ?> (Blue)</td>
</tr>
  <tr><th><? echo ProductSETS->Entity->[1]->Specification2 ?>:</th>
<td><? echo ProductSETS->Entity->[101]->Title->Value ?> (Round)</td> </tr>
}
endforeach;

如果 $filter = "101" 仅针对产品 ID 101 绘制表格但仍使用来自 id 的数据的选择性列表。 1 显示单个 ID 101 产品的人类可读产品规格:

foreach ($feed->ProductSETS->Entity) :
  if(ProductSETS->Entity->id == "101"){
  <tr><th><? echo ProductSETS->Entity->[1]->Specification1 ?>:</th>
<td><? echo ProductSETS->Entity->[101]->Title->Value ?> (Blue)</td> </tr>
  <tr><th><? echo ProductSETS->Entity->[1]->Specification2 ?>:</th>
<td><? echo ProductSETS->Entity->[101]->Title->Value ?> (Round)</td> </tr>
  }else{ echo "No matching product search criteria"; }
endforeach;

我认为我的“解释技巧”是最好的,对于“故事”的长度感到抱歉,希望有人可以帮助我。

【问题讨论】:

    标签: php html-table xml-parsing


    【解决方案1】:

    找到了解决方案。代码由Barand 编写,脚本执行以下操作:

    • 解析具有多个实体条目的 XML 数据
    • 使用第一个条目作为“标题”列(条目 ID 1)
    • 在“可比较样式”水平 html 表中的列中相互输出条目
    • 具有“过滤”模式,可以“比较”某些条目
    • 仅修改第一个条目的值(以删除默认的“1”值)

    脚本不会重新组织 HTML 表中的条目(行)(它们与 XML 数据的顺序相同)。

    <?php
    // Code writen by Barand - https://forums.phpfreaks.com/profile/3105-barand/
    // Donate to Barand - https://www.paypal.me/baandrew - if you found this script usefull !
    $xml = "
    <Message>
        <EntityType>Document</EntityType>
        <ProductSETS>
          <Entity>
           <id>1</id>
           <sku>1</sku>
           <ean>1</ean>
           <Specification1>Name</Specification1>
           <Specification2>Color</Specification2>
           <Specification3>Type</Specification3>
           <Specification4>Manufacturer</Specification4>
           <Price>Product Price</Price>
          </Entity>
        
          <Entity>
           <id>100</id>
           <sku>prod-0001</sku>
           <ean>5901234123456</ean>
           <Specification1>Lorem ipsum</Specification1>
           <Specification2>Red</Specification2>
           <Specification3>Hybrid car</Specification3>
           <Specification4>Tesla</Specification4>
           <Price>10000</Price>
           </Entity>
        
          <Entity>
           <id>101</id>
           <sku>prod-0002</sku>
           <ean>5907171819916</ean>
           <Specification1>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia</Specification1>
           <Specification2>Blue</Specification2>
           <Specification3>Diesel car</Specification3>
           <Specification4>Trabant</Specification4>
           <Price>5000</Price>
           </Entity>
    
          <Entity>
           <id>102</id>
           <sku>prod-0003</sku>
           <ean>6189192737718</ean>
           <Specification1>Ut enim ad minim veniam quis nostrud exercitation</Specification1>
           <Specification2>Black</Specification2>
           <Specification3>SUV</Specification3>
           <Specification4>Hummer</Specification4>
           <Price>1</Price>
           </Entity>
           
           
        </ProductSETS>
    </Message>
    ";
    $chosen = $_GET['choice'] ?? [];
    
    $feed = simplexml_load_string($xml);
    $heads = $prods = [];
    $tdata = '';
    
    if ($chosen) {
        $h = $feed->xpath('//Entity[id = 1]')[0];         // headings from entity #1
        $p = $feed->xpath('//Entity[id > 1]');            // products from rest of entities
        foreach ($h as $k=>$v) {
            $heads[$k] = (in_array($k, ['id','sku','ean'])) ? '' : (string)$h->$k;
            if (!isset($prods[$k])) {
                $prods[$k] = [ 'heading' => $heads[$k],
                               'specs'   => []
                             ];
            }
        }
        foreach ($p as $spec) {
            if (!in_array((string)$spec->id, $chosen)) continue;
            foreach ($spec as $k=>$s) {
                $prods[$k]['specs'][] = trim((string)$s);
            }
        }
    
        foreach ($prods as $k => $row) {
            if ($k=='id') continue;
            $tdata .= "<tr><th>{$row['heading']}</th>";
            $tdata .= '<td>' . join('</td><td>', $row['specs']) . "</td></tr>\n";
        }
    }
    /**
    * build list of checkbox options for product selection
    * 
    * @param simplexmlobj $feed
    */
    function productOptions($feed) 
    {
        $prods = $feed->xpath('//Entity[id > 1]');
        $opts = '';
        foreach ($prods as $p) {
            $opts .= "&emsp;<label><input type='checkbox' name='choice[]' value='{$p->id}'> {$p->sku}</label>\n";
        }
        return $opts;
    }
    ?>
    <!DOCTYPE html>
    <html lang='en'>
    <head>
    <title>Example</title>
    <meta charset='utf-8'>
    <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
    <style type='text/css'>
        td {
            width: 20%;
            padding: 8px;
        }
        th {
            width: 20%;
            padding: 8px;
            text-align: left;
            background-color: black;
            color: white;
        }
    </style>
    </head>
    <body>
    <div class="w3-container w3-blue-gray w3=padding">
        <h1>Product Comparison</h1>
    </div>
    <form class="w3-container w3-light-gray w3-padding-24">
        Select products to compare &emsp; <?=productOptions($feed)?>
        &emsp;
        <button class='w3-button w3-blue w3-round'>Compare</button>
    </form>   
    <div class="w3-continer w3-responsive w3-padding w3-margin-top">
        <table class="w3-table-all">
            <?= $tdata ?>
        </table>
    </div>
    </body>
    </html>
    

    结果是:

    【讨论】:

      猜你喜欢
      • 2017-05-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-03
      • 2013-07-08
      • 2013-04-24
      • 2012-02-07
      • 1970-01-01
      相关资源
      最近更新 更多