我正在使用xpath从文档中获取信息,唯一的问题是我无法将它们组合成1 for循环,因此信息在页面上正确显示。我的代码是:
<?php
$doc = new DOMDocument;
$doc->preserveWhiteSpace = FALSE;
$doc->load('http://mdoerrdev.com/xml/updates-mits.xml');
$xpath = new DOMXPath($doc);
$xpath->registerNamespace('MITS', "http://www.mitsproject.org/namespace");
$unitName = $xpath->evaluate("//ILS_Unit[@FloorplanID='550584']/Unit/MITS:MarketingName");
$unitPrice = $xpath->evaluate("//ILS_Unit[@FloorplanID='550584']/Unit/MITS:Information/MITS:MarketRent");
?>
<div class="unit-name">
<?php
foreach ($unitName as $un) {
echo $un->nodeValue . "\n";
}
?>
</div>
<div class="floor-plan-box fpb-one-bedroom cleafix"> <?php
foreach ($unitPrice as $up) {
echo $up->nodeValue . "\n";
?><img src='<?php bloginfo('stylesheet_directory'); ?>/img/floorplans/<?php echo "550584" ?>.jpg' /> <?php
};
?>
</div>
(来自:http://pastie.org/8360106)
我需要将MarketRent和MarketingName信息组合在一起,而不是像在当前代码中那样单独显示它们。
答案 0 :(得分:3)
这取决于你想要实现的目标。您可以使用 Union 运算符(管道|
)组合两个xpath表达式:
$unitName = $xpath->evaluate("
(
//ILS_Unit[@FloorplanID='550584']/Unit/MITS:MarketingName
|//ILS_Unit[@FloorplanID='550584']/Unit/MITS:Information/MITS:MarketRent
)
");
然后按文档顺序返回所有已评估的节点:
<div class="unit-name">
1265.0000
C-304
1265.0000
C-308
1255.0000
C-204
1255.0000
C-208
1230.0000
C-102
1230.0000
C-103
</div>
这可能不是你想要的。相反,您希望同时评估两个结果,这可以使用MultipleIterator
:
$unitName = $xpath->evaluate("//ILS_Unit[@FloorplanID='550584']/Unit/MITS:MarketingName");
$unitPrice = $xpath->evaluate("//ILS_Unit[@FloorplanID='550584']/Unit/MITS:Information/MITS:MarketRent");
$it = new MultipleIterator();
$it->attachIterator(new IteratorIterator($unitName));
$it->attachIterator(new IteratorIterator($unitPrice));
foreach($it as $value) {
list($name, $price) = $value;
echo " * ", $name->nodeValue, " ", $price->nodeValue, "\n";
}
输出:
* C-304 1265.0000
* C-308 1265.0000
* C-204 1255.0000
* C-208 1255.0000
* C-102 1230.0000
* C-103 1230.0000
这可能是您正在寻找的更多内容。另外,对于你所做的事情,SimpleXMLElement 可能更容易使用,因为它已经允许在字符串上下文中输出节点。
此外,还有另一个概念可以将浅层对象直接映射到基础XML文档,这里概述了它:
这是一个非常有趣的概念。 IIRC我写了类似的东西,比如将一个xpath查询应用到另一个节点的所有节点上,但我现在还没找到它。
答案 1 :(得分:3)
我无法抗拒另外尝试在某些XML源上应用模型。我为这个答案选择了SimpleXMLElement
。它只是透明的,并且几乎只对xpath表达式有影响。应该可以将同一个界面翻译为DOMDocument
。
$unitPrototype = new XPrototype(
"//ILS_Unit[@FloorplanID='550584']/Unit",
[
'name' => 'MITS:MarketingName',
'price' => 'MITS:Information/MITS:MarketRent'
]
);
$units = new XList('http://mdoerrdev.com/xml/updates-mits.xml', $unitPrototype);
foreach ($units as $unit) {
echo
$unit->name, " ",
$unit->price, "\n";
}
XPrototype
和XList
等已使用类型的来源位于Github:XObjects.php
。
答案 2 :(得分:2)
使用$xpath->evaluate()
...
您的代码进行了这些调整:
<?php
$doc = new DOMDocument;
$doc->preserveWhiteSpace = false;
$doc->load('http://mdoerrdev.com/xml/updates-mits.xml');
$xpath = new DOMXPath($doc);
$xpath->registerNamespace('MITS', "http://www.mitsproject.org/namespace");
$units = $xpath->evaluate("//ILS_Unit[@FloorplanID='550584']/Unit");
echo "<table>";
echo "<tr><th>Marketing Name</th><th>Market Rent</th></tr>";
foreach($units as $unit) {
$marketingName = $xpath->evaluate("string(MITS:MarketingName)", $unit);
$marketRent = $xpath->evaluate("string(MITS:Information/MITS:MarketRent)", $unit);
echo "<tr>";
echo " <td>" . $marketingName . "</td>";
echo " <td>" . $marketRent . "</td>";
echo "</tr>";
}
echo "</table>";
?>
根据您的请求,将MarketingName和MarketRent一起显示而不是单独显示,从而产生此输出: