PHP 解析 XML 数据并绘制 HTML Table
PHP parsing XML data and draw HTML Table
我有一个案例需要解析“产品规格”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 数据的 table,例如:
_____________________________________________________________________
| 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 始终将第一个实体作为类似“header”的条目,其中 1 用于映射产品规格标题的“人类可读”值
在“header”实体之后,存在实际产品规格值(颜色、尺寸、价格等)
要注意的是,我需要两种方法来在 HTML 中显示 table,其值来自 XML 数据:
全部列出(没有带有 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;
选择性列表table where if a $filter = "101" draw table 仅为产品 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;
我想我已经充分利用了我的“解释技巧”,对于“故事”的长度感到抱歉,希望有人能帮助我。
已找到解决方案。代码由 Barand 编写,脚本执行此操作:
- 解析具有多个实体条目的 XML 数据
- 使用第一个条目作为“标题”列(条目 ID 1)
- 在“comparable-style”水平方向htmltable
的列中相互输出条目
- 具有“过滤”模式,可以对某些条目进行“比较”
- 仅修改第一个条目的值(删除默认“1”值)
脚本不会重新组织 HTML table 中的条目(行)(它们与 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 .= " <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   <?=productOptions($feed)?>
 
<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>
我有一个案例需要解析“产品规格”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 数据的 table,例如:
_____________________________________________________________________
| 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 始终将第一个实体作为类似“header”的条目,其中 1 用于映射产品规格标题的“人类可读”值 在“header”实体之后,存在实际产品规格值(颜色、尺寸、价格等)
要注意的是,我需要两种方法来在 HTML 中显示 table,其值来自 XML 数据:
全部列出(没有带有 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;
选择性列表table where if a $filter = "101" draw table 仅为产品 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;
我想我已经充分利用了我的“解释技巧”,对于“故事”的长度感到抱歉,希望有人能帮助我。
已找到解决方案。代码由 Barand 编写,脚本执行此操作:
- 解析具有多个实体条目的 XML 数据
- 使用第一个条目作为“标题”列(条目 ID 1)
- 在“comparable-style”水平方向htmltable 的列中相互输出条目
- 具有“过滤”模式,可以对某些条目进行“比较”
- 仅修改第一个条目的值(删除默认“1”值)
脚本不会重新组织 HTML table 中的条目(行)(它们与 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 .= " <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   <?=productOptions($feed)?>
 
<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>