SimpleXML 和 php - 获取包含与另一个节点匹配的文本的节点
Posted
技术标签:
【中文标题】SimpleXML 和 php - 获取包含与另一个节点匹配的文本的节点【英文标题】:SimpleXML and php - get a node that contains text that matches another node 【发布时间】:2014-06-21 21:05:29 【问题描述】:如果该节点的内容与另一个节点(兄弟)匹配,我正在尝试显示该节点的文本内容。这是 XML:
<MemberId>
<BillingInfo>
<Details>
<Line NUMBER="0">
<ChargeDate>20140605</ChargeDate>
<DueDate>20140605</DueDate>
<TrackingNumber>PR DED</TrackingNumber>
<Description>Account payroll deduction</Description>
<RevCode>SJ1550</RevCode>
<RevDesc>ACCOUNT PAYROLL DEDUCTION</RevDesc>
<SalesAmount>-11.77</SalesAmount>
<ServiceCharge>0.00</ServiceCharge>
<GST>0.00</GST>
<PST>0.00</PST>
<Othertaxes>0.00</Othertaxes>
<Total>-11.77</Total>
<ChitCode>PR DED</ChitCode>
<ChitDate>20140605</ChitDate>
</Line>
<Line NUMBER="1">
<ChargeDate>20140605</ChargeDate>
<DueDate>20140605</DueDate>
<TrackingNumber>03128862</TrackingNumber>
<Description>Mountain Mkt Sales</Description>
<RevCode>SJ1553</RevCode>
<RevDesc>MOUNTAIN MKT SALES</RevDesc>
<SalesAmount>8.99</SalesAmount>
<ServiceCharge>0.00</ServiceCharge>
<GST>0.00</GST>
<PST>0.61</PST>
<Othertaxes>0.00</Othertaxes>
<Total>9.60</Total>
<ChitCode>03128862</ChitCode>
<ChitDate>20140605</ChitDate>
</Line>
</Details>
</BillingInfo>
<Chits>
<Chit>
<Code>03128862</Code>
<Body><![CDATA[
Member#: 0ECHER
Name: *******
Area: *********
Server: JEANNEANE
Chit#: 03128862
Date: June 5 2014
------- ------- ------- ------- -------
1 MINGUA BEEF JER 8.99
------- ------- ------- ------- -------
Sub-Total 8.99
TAX 0.61
------- ------- ------- ------- -------
Chit Total 9.60
MEMBER CHARGE -9.60
]]></Body>
</Chit>
</Chits>
</MemberId>
我成功地显示了每个 ChitCode 和 ChitDate,因为它们位于 Line[@number] 节点中。我想显示包含文本“Chit#: XXXXXX”的 Body 节点,其中 xxxxxx 匹配 Line->ChitCode。这是我的 php,它显示了正文,但它显示了所有行项目的第一个正文:
<?php
foreach($Chitquery as $Chit)
foreach($Linequery as $Line)
echo "<label class='collapse' for='".$Line->ChitCode."-".$Line->ChitDate."'>".$Line->Description."</label>
<input id='".$Line->ChitCode."-".$Line->ChitDate."' type='checkbox'>
<div>";
// Creates hide - show link for each Description item
// Start getting the matching Chit Code from Chit/Body
if ($Chit->Code = $Line->ChitCode)
echo $Chit->Body."</div>";
else
echo " ".$Line->ChitCode."</div>";
// End If
//End foreach Linequery
// End foreach Chitquery
?>
这是回声 $Chit->Body。"";我需要帮助,我想显示包含 $Line->ChitCode 值的 Body。
哦,是的,由于“foreach”语句的放置不当,这些行重复得很奇怪! 帮助!提前致谢!
更新:我已经更改了我的 php 代码,现在我可以使用隐藏显示 div,没有重复,但我得到的是 'array' 而不是 $ChitBody。我无法弄清楚如何在 $ChitBody = $member->xpath('Chits/Chit/Body[text()="'.$Line->ChitCode.'" 中找到包含 $Line->ChitCode 的 Body 节点] ');
<?php
foreach($Linequery as $Line)
$ChitCode = $member->Chits->Chit->Code;
$ChitBody = $member->xpath('Chits/Chit/Body[text()="'.$Line->ChitCode.'"] ');
echo "<label class='collapse' for='".$Line->ChitCode."-".$Line->ChitDate."'>".$Line->Description."</label>
<input id='".$Line->ChitCode."-".$Line->ChitDate."' type='checkbox'>"; // Creates hide - show link for each Description item
// Start getting the matching Chit Code from Chit/Body
if ($ChitCode = $Line->ChitCode)
echo "<div>Code: ".$ChitCode."<br>".$ChitBody."</div>";
else
echo "<div>".$Line->ChitCode."</div>";
// End If
//End foreachLinequery
?>
【问题讨论】:
if 语句中有 $Chit->Code = $Line->ChitCode。尝试将其更改为 $Chit->Code == $Line->ChitCode. 【参考方案1】:您很可能正在寻找 xpath 来查询您的文档。
例如遍历行 - 我不完全理解您为什么要这样做,但这是我理解的遍历行的方式(纯文本输出):
$xml = simplexml_load_string($buffer);
foreach ($xml->xpath('//Details/Line') as $line)
printf("#%d: %s\n", $line['NUMBER'], $line->Description);
给出:
#0: Account payroll deduction
#1: Mountain Mkt Sales
我想你知道这通常是如何工作的。因此,现在基于$line->ChitCode
获取信息,我认为这对您来说实际上是更有趣的部分。它也更好地说明了 xpath 的好处:
foreach ($xml->xpath('//Details/Line') as $line)
printf("#%d: [%s] %s\n", $line['NUMBER'], $line->ChitCode, $line->Description);
$query = sprintf("//Chits/Chit[Code = '%s']/Body", $line->ChitCode);
$result = $xml->xpath($query);
if ($result)
$chit = $result[0];
echo $chit;
else
echo ' -- no chit found -- ';
echo "\n";
这次查询包含查找数字的条件(如果你想保存,escape the string properly (more info)),它基本上创建了以下两个 xpath 查询:
//Chits/Chit[Code = 'PR DED']/Body
//Chits/Chit[Code = '03128862']/Body
我再次猜想你可以想象这些是什么意思。如果找到这样的<Body>
元素,上面的代码会输出它。结果是这样的:
#0: [PR DED] Account payroll deduction
-- no chit found --
#1: [03128862] Mountain Mkt Sales
Member#: 0ECHER
Name: *******
Area: *********
Server: JEANNEANE
Chit#: 03128862
Date: June 5 2014
------- ------- ------- ------- -------
1 MINGUA BEEF JER 8.99
------- ------- ------- ------- -------
Sub-Total 8.99
TAX 0.61
------- ------- ------- ------- -------
Chit Total 9.60
MEMBER CHARGE -9.60
我希望这能让您有足够的洞察力来开始使用它。 xpath()
is just a method on SimpleXMLElement 所以你也可以将它与我没有复制的代码结合起来,只是为了让示例更小(与我在这里使用纯文本输出的原因相同,与 html 相同,但会使示例膨胀)。
由 OP 添加:
效果很好!!
我已将您的代码调整为适用于此,并且效果很好:
foreach ($Linequery as $Line)
$LineChitCode = $Line->ChitCode;
$ChitBody = sprintf("//Chits/Chit[Code = '%s']/Body", $LineChitCode);
$CBresult = $member->xpath($ChitBody);
echo "<label class='collapse' for='" . $Line->ChitCode . "-" . $Line->ChitDate . "'>" . $Line->Description . "</label>
<input id='" . $Line->ChitCode . "-" . $Line->ChitDate . "' type='checkbox'>"; // Creates hide - show link for each Description item
// Start getting the matching Chit Code from Chit/Body
if ($CBresult)
$chit = $CBresult[0];
echo "<div>Code: " . $LineChitCode . "<br>" . $chit . "</div>";
else
echo "<div>" . $Line->ChitCode . "</div>";
谢谢,你让我免于花 3 天时间来解决这个问题!
【讨论】:
@CharlieTrig:您也可以使用 xpath 查找兄弟姐妹,但这种方式更直接。仅供参考:)【参考方案2】:你可以使用 if ($Chit->Code == $Line->ChitCode) 而不是 if ($Chit->Code = $Line->ChitCode)
【讨论】:
那行不通。仍然有重复,并且不显示与 $Line->ChitCode 的 Body 匹配以上是关于SimpleXML 和 php - 获取包含与另一个节点匹配的文本的节点的主要内容,如果未能解决你的问题,请参考以下文章