PHP XPath 获取属性值的一部分
PHP XPath to get a part of an attribute value
我必须解析一个显示通话清单的 HTML 网站。转换为 XML 后,结构为:
<body>
<form name="mainform" method="POST" action="baz" class="all">
<input type="submit" value="" style="position:absolute;top:-9999px;left:-9999px;" name="apply"/>
<p>foo</p>
<div class="bar">
..
</div>
<br/>
<div class="onPageTabsBox">
<ul class="tabs onPageTabs">
...
</ul>
</div>
<table id="baz">
<tr class="thead">
...
</tr>
</table>
<div id="uiScroll">
<table id="bla">
<tr class="showif_in">
...
</tr>
...
<tr class="showif_out">
<td class="call_out" title="outbound call" datalabel="29.12.19 11:13"/>
<td>29.12.19 11:13</td>
<td title="Doe, John (privat) = 0123456789" datalabel="Name / Rufnummer">
<a href=" " onclick="return onDial('0123456789');">Doe, John (privat)</a>
</td>
<td datalabel="foo">bar</td>
<td title="987654 (Internet)" datalabel="own number">987654</td>
<td class="duration" data-timestr="0:02" datalabel="duration">2 Min</td>
<td class="btncolumn">
...
</td>
</tr>
<tr class="showif_out">
...
</tr>
我需要的功能是从来电、去电...中获取 phone 号码。
所以我尝试从 td
节点获取 phone 数字,其中 title
包含 " = "
目前功能是这样的:
function getCallList($config, string $type = '')
{
...
$xmlSite = convertHTMLtoXML($response);
switch ($type) {
case 'in':
case 'out':
case 'fail':
case 'rejected':
$query = sprintf('//form/div/table/tr[@class="showif_%s"]', $type);
break;
default: // get all recorded calls
$query = '//form/div/table/tr';
}
$rows = $xmlSite->xpath($query);
foreach ($rows as $row) {
$numbers = $row->xpath('substring-after(//td[@title], " = ")');
}
...
}
在这里咨询了类似的问题后,我尝试了 $numbers = $row->evaluate('substring-after(//td[@title], " = ")');
和其他几个 xPath 表达式 - 不幸的是我无法获取子字符串。除此之外,我怀疑只需要一个查询就可以得到一个包含 phone 个数字的数组。
如前所述 here and ,很遗憾,您无法使用 XPath 1.0 在一次查询中完成此操作。
您可以做的是列出属于这些 <td>
的所有 title
属性,然后使用 preg_match
获取 =
之后的所有内容空格:
$rowTitleAttrs = $xmlSite->xpath('//tr[@class="showif_out"]/td/@title');
$phoneNumbers = [];
foreach ($rowTitleAttrs as $rowTitleAttr) {
if (preg_match('/(?<= = )(?<phoneNumber>.*?)$/', $rowTitleAttr->title, $matches)) {
$phoneNumbers[] = $matches['phoneNumber'];
}
}
我在此过程中冒昧地简化了您的 XPath 查询,因为 class 名称 应该 足够准确,不必说明通向的整个路径它。
我必须解析一个显示通话清单的 HTML 网站。转换为 XML 后,结构为:
<body>
<form name="mainform" method="POST" action="baz" class="all">
<input type="submit" value="" style="position:absolute;top:-9999px;left:-9999px;" name="apply"/>
<p>foo</p>
<div class="bar">
..
</div>
<br/>
<div class="onPageTabsBox">
<ul class="tabs onPageTabs">
...
</ul>
</div>
<table id="baz">
<tr class="thead">
...
</tr>
</table>
<div id="uiScroll">
<table id="bla">
<tr class="showif_in">
...
</tr>
...
<tr class="showif_out">
<td class="call_out" title="outbound call" datalabel="29.12.19 11:13"/>
<td>29.12.19 11:13</td>
<td title="Doe, John (privat) = 0123456789" datalabel="Name / Rufnummer">
<a href=" " onclick="return onDial('0123456789');">Doe, John (privat)</a>
</td>
<td datalabel="foo">bar</td>
<td title="987654 (Internet)" datalabel="own number">987654</td>
<td class="duration" data-timestr="0:02" datalabel="duration">2 Min</td>
<td class="btncolumn">
...
</td>
</tr>
<tr class="showif_out">
...
</tr>
我需要的功能是从来电、去电...中获取 phone 号码。
所以我尝试从 td
节点获取 phone 数字,其中 title
包含 " = "
目前功能是这样的:
function getCallList($config, string $type = '')
{
...
$xmlSite = convertHTMLtoXML($response);
switch ($type) {
case 'in':
case 'out':
case 'fail':
case 'rejected':
$query = sprintf('//form/div/table/tr[@class="showif_%s"]', $type);
break;
default: // get all recorded calls
$query = '//form/div/table/tr';
}
$rows = $xmlSite->xpath($query);
foreach ($rows as $row) {
$numbers = $row->xpath('substring-after(//td[@title], " = ")');
}
...
}
在这里咨询了类似的问题后,我尝试了 $numbers = $row->evaluate('substring-after(//td[@title], " = ")');
和其他几个 xPath 表达式 - 不幸的是我无法获取子字符串。除此之外,我怀疑只需要一个查询就可以得到一个包含 phone 个数字的数组。
如前所述 here and
您可以做的是列出属于这些 <td>
的所有 title
属性,然后使用 preg_match
获取 =
之后的所有内容空格:
$rowTitleAttrs = $xmlSite->xpath('//tr[@class="showif_out"]/td/@title');
$phoneNumbers = [];
foreach ($rowTitleAttrs as $rowTitleAttr) {
if (preg_match('/(?<= = )(?<phoneNumber>.*?)$/', $rowTitleAttr->title, $matches)) {
$phoneNumbers[] = $matches['phoneNumber'];
}
}
我在此过程中冒昧地简化了您的 XPath 查询,因为 class 名称 应该 足够准确,不必说明通向的整个路径它。