2

我正在使用 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 信息组合在一起,而不是像在当前代码中那样单独显示它们。

4

3 回答 3

3

这在一定程度上取决于您要达到的目标。您可以使用联合运算符 (pipe |) 组合两个 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 查询应用于另一个的所有节点,但我现在找不到。

于 2013-09-27T16:39:23.067 回答
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";
}

所用类型的来源如XPrototypeXList在 Github: 上XObjects.php

于 2013-09-27T19:46:19.393 回答
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 一起显示而不是根据您的请求单独显示此输出:

在此处输入图像描述

于 2013-09-27T16:45:46.680 回答