如何使用 PHP 获取 XML 属性值
How to get XML attribute values using PHP
我正在尝试从 xml 属性中获取值。但我只得到第一个书架库存价值,但我没有得到第二个库存价值。当没有像书 ID="5"
中那样的股票价值时,我如何显示 EmptyXML test.xml
<?xml version="1.0" encoding="utf-8"?>
<bookstore Code="111">
<bookshelf Date="01/26/2021" Time="7:35 PM" Note=" ">
<book ID="3" Name="website1">
<stock price="10" Name="Name5"/>
</book>
<book ID="4" Name="website 2">
<stock price="12" Name="Name2"/>
</book>
<book ID="7" Name="website 3">
<stock price="10.50" Name="Name3" />
</book>
<book ID="5" Name="website 4" />
</bookshelf>
<bookshelf Date="01/25/2021" Time="7:35 PM" Note=" ">
<book ID="3" Name="website1"/>
<book ID="4" Name="website 2"/>
<book ID="7" Name="website 3"/>
<book ID="5" Name="website 4" />
</bookshelf>
</bookstore>
PHP 代码
<?php $mybooks = simplexml_load_file('test.xml');?>
<table width="100%" border="1">
<tbody>
<tr>
<td>Bookshelf Date</td>
<td>website1</td>
<td>website2</td>
<td>website3</td>
<td>website4</td>
</tr>
<tr><td><?php echo $bookshelf['Date']; ?></td>
<?php
foreach($mybooks->bookshelf->book as $d) {
$d['Name'].' '.$d['ID'].'<br>';
foreach( $d->stock as $stocks) {
$stocks['price'].' '.$stocks['Name']."\n";
?>
<td><?php echo $stocks['price'].' '.$stocks['Name']."\n"; ?> </td>
<?php }} ?></tr></tbody>
</table>
更新: 如果从一个书架 -> 书中没有数据怎么办。如果那个书架正在获取数据或隐藏它而不显示它,我该如何检查它。
我为您提供了 3 种方法来实现您的最终目标 - 诚然只有一种使用 simple_xml
方法#1:简单XML
由于您希望在 table 中每行显示所有网站,因此您需要嵌套查询。对 return 行(书架)的外部查询和对 return 该书架上书籍的内部查询。当涉及到特定书籍不存在的 stock
节点时,如果 stock
标签不存在,我使用三元运算符 select 另一个值。
<?php
$xmlfile='test.xml';
$mybooks = simplexml_load_file( $xmlfile );
?>
<table border=1 cellspacing=5 cellpadding=5>
<thead>
<tr>
<th>Bookshelf Date</th>
<th>Website 1</th>
<th>Stock</th>
<th>Website 2</th>
<th>Stock</th>
<th>Website 3</th>
<th>Stock</th>
<th>Website 4</th>
<th>Stock</th>
</tr>
</thead>
<tbody>
<?php
foreach( $mybooks->bookshelf as $shelf ) {
?>
<tr>
<td><?php echo $shelf['Date'];?></td>
<?php
foreach( $shelf->book as $book ){
?>
<td><?php echo $book['Name'];?></td>
<td>
<?php
$stock=$book->stock ? $book->stock['price'] : 'None';
echo $stock;
?>
</td>
<?php
}
?>
</tr>
<?php
}
?>
</tbody>
</table>
输出:
方法 #2:DOM文档和 XPath
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title></title>
</head>
<body>
<table border=1 cellspacing=5 cellpadding=5>
<tr>
<th>Bookshelf Date</th>
<th>Website 1</th>
<th>Stock</th>
<th>Website 2</th>
<th>Stock</th>
<th>Website 3</th>
<th>Stock</th>
<th>Website 4</th>
<th>Stock</th>
</tr>
<?php
$xml='<?xml version="1.0"?>
<bookstore Code="111">
<bookshelf Date="01/26/2021" Time="7:35 PM" Note=" ">
<book ID="3" Name="website 1">
<stock price="10" Name="Name5"/>
</book>
<book ID="4" Name="website 2">
<stock price="12" Name="Name2"/>
</book>
<book ID="7" Name="website 3">
<stock price="10.50" Name="Name3" />
</book>
<book ID="5" Name="website 4" />
</bookshelf>
<bookshelf Date="01/26/2021" Time="7:35 PM" Note=" ">
<book ID="3" Name="website 1">
<stock price="110" Name="Name5"/>
</book>
<book ID="4" Name="website 2">
<stock price="112" Name="Name2"/>
</book>
<book ID="7" Name="website 3">
<stock price="110.50" Name="Name3" />
</book>
<book ID="5" Name="website 4" />
</bookshelf>
</bookstore>';
$dom=new DOMDocument;
$dom->loadXML( $xml );
$xp=new DOMXPath( $dom );
$expr='//bookshelf';
$col=$xp->query( $expr );
if( $col->length > 0 ){
foreach( $col as $shelf ){
$tmp=[ $shelf->getAttribute('Date') . ' ' . $shelf->getAttribute('Time') ];
$bookcol=$xp->query('book', $shelf);
if( $bookcol->length > 0 ){
foreach( $bookcol as $book ){
$stock=$xp->query('stock', $book );
$stock=( $stock->length > 0 ) ? $stock->item(0)->getAttribute('price') : 'None';
$tmp[]=$book->getAttribute('Name');
$tmp[]=$stock;
}
}
printf('
<tr>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
<td>%s</td>
</tr>',
...$tmp
);
}
}
?>
</table>
</body>
</html>
输出:
方法 #3:DOM 文档和 XSLTProcessor - XSL 样式表
XSL 样式表
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- we want to output a portion of html -->
<xsl:output method='html' standalone='yes' indent='yes' encoding='utf-8'/>
<xsl:template match="/">
<style>
table.xml{
border:1px solid gray;
display:table;
border-collapse:collapse;
border-spacing:0px;
empty-cells:show;
table-layout:auto;
font-family:Verdana, Geneva, Arial, Helvetica, sans-serif;
font-size:0.8rem;
}
table.xml tr:first-of-type{
background:#2f4f4f;
color:white;
}
table.xml tr:nth-of-type( even ) td{
background:aliceblue;
}
table.xml td{
margin:0;
padding:5px;
border-bottom:1px dotted rgba(133,133,133,0.5);
}
</style>
<table class='xml' border='1' cellspacing='5' cellpadding='5'>
<tr>
<th>Bookshelf Date</th>
<th>Website 1</th>
<th>Stock</th>
<th>Website 2</th>
<th>Stock</th>
<th>Website 3</th>
<th>Stock</th>
<th>Website 4</th>
<th>Stock</th>
</tr>
<xsl:for-each select="bookstore/bookshelf">
<tr>
<xsl:attribute name='data-id'>
<xsl:value-of select="book/@ID"/>
</xsl:attribute>
<td><xsl:value-of select="@Date"/></td>
<xsl:for-each select="book">
<td><xsl:value-of select="@Name"/></td>
<td>
<xsl:attribute name='data-name'>
<xsl:value-of select="stock/@Name"/>
</xsl:attribute>
<xsl:choose>
<xsl:when test="stock/@price !=''">
<xsl:value-of select="stock/@price"/>
</xsl:when>
<xsl:otherwise>
None
</xsl:otherwise>
</xsl:choose>
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
和 PHP 加载和处理它
<?php
$xmlfile='c:/wwwroot/xml/bookstore.xml';
$xslfile='c:/wwwroot/xsl/bookstore.xsl';
$dom=new DOMDocument;
$dom->load( $xmlfile );
$css=new DOMDocument;
$css->load( $xslfile );
$xsl=new XSLTProcessor;
$xsl->importStyleSheet( $css );
$html=$xsl->transformToXML( $dom );
header('Content-Type: text/html');
exit( $html );
?>
输出:
更新
基于修改后的 XML 和上面的评论:
<?php
$data=[];
foreach( $mybooks->bookshelf as $shelf ) {
$row=[];
$books=$shelf->children();
if( !empty( $books ) ){
if( $books->children() && count( $books->children() ) > 0 ){
$row[]=sprintf('<tr data-date="%s" data-time="%s" data-note="%s">', $shelf['Date'], $shelf['Time'], $shelf['Note'] );
$row[]=sprintf('<td>%s</td>',implode(', ', [ $shelf['Date'], $shelf['Time'] ] ) );
$cells=[];
foreach( $books as $book ){
if( $book->stock ){
$cells[]=sprintf('<td>%s</td>', $book['Name'] );
$cells[]=sprintf('<td>%s</td>',$book->stock['price']);
}
}
$row[]=implode( PHP_EOL, $cells );
$row[]='</tr>';
}
}
#append
$data[]=implode( PHP_EOL, $row );
}
# output
echo implode( PHP_EOL, $data );
$mybooks = $data = $row = $cells = $books = $book = $shelf = null;
?>
哪个输出: