已经尝试了几天解析下面的html代码(请注意,没有真正的分层树结构)。一切都在同一水平上。
<p><span class='one'>week number</span></p>
<p><span class='two'>day of the week</span></p>
<table class='spreadsheet'>
table data
</table>
<p><span class='two'>another day of the week</span></p>
<table class='spreadsheet'>
table data
</table>
<p><span class='one'>another week number</span></p>
ETC
我基本上想要做的是,浏览每个dom元素,检查它是否是一周,如果是,将该周的所有日期添加到该特定周,并将所有表数据添加到相应的一周中的天。所以有以下结构:
array {
31 => array {
monday => array {
data => table data
}
tuesday => array {
data => table data
}
}
32 => array {
monday => array {
data => table data
}
tuesday => array {
data => table data
}
}
}
这是我到目前为止的PHP代码。
$d = new DomDocument;
@$d->loadHtml($html);
$xp = new DomXpath($d);
$res = $xp->query( "//*[@class='one' or @class='two' or @class='spreadsheet']" );
foreach ($res as $dn) {
$nodes = $dn->childNodes;
foreach ($nodes as $node) {
if ($node->nodeValue != "") {
echo $node->nodeValue;
}
}
}
有些人在stackoverflow上向我倾斜使用Xpath来实现这一点,上面的代码分别处理每个节点。我认为我需要做的是获取所有“周”节点,然后获取他们的下一个兄弟节点,从那里检查它是否是一天,如果是这样,将它添加到该数组,如果它是“周”节点,创建一个新的数组等
过去几天我一直在用头发撕掉头发,所以任何帮助/推动正确的方向都会非常感激!!!
干杯, Dandoen
答案 0 :(得分:1)
<强>更新;见下文。
如果您希望到目前为止已尝试过tell us what the output is代码,那将会有所帮助。这将有助于我们了解已经有效的东西和仍然存在的东西。但是,这就是我看到你对XPath和DOM的使用。 (免责声明:我的专长是XPath和DOM,而不是PHP。)
$res = $xp->query( "//*[@class='one' or @class='two' or @class='spreadsheet']" );
此XPath查询将为您提供样本中的所有<span>
和<table>
个节点,因为这些节点是您要求的类的元素。
foreach ($res as $dn) {
迭代span和table元素。在这个循环中你可能想说if ($dn->getAttribute("class") == "one") ...
,如果是这样,你的数组结构开始新的一周;如果课程是“两个”,请在当前周添加新的工作日等等。
$nodes = $dn->childNodes;
在这里,您要求当前span或table元素的子节点。对于跨度,您显示的唯一子节点是文本节点,例如“一周中的另一天”。对于table元素,我们假设有tr
个元素等。
foreach ($nodes as $node) {
迭代span中的单个文本节点(或表的子元素):
if ($node->nodeValue != "") {
echo $node->nodeValue;
}
打印文本节点的文本内容(span
元素的子元素);或'null' if we're looking at an element(与tr
的{{1}}子项一样。)
这就是上面的代码似乎正在做的事情。如果它的行为与描述不符,请发布有关实际输出的信息,我们可能会提供帮助。如果它的行为如上所述,但您需要有关创建周数组元素的部分的帮助,请告诉我们。
<强>更新强>
我建议您使用此XPath查询:
table
获取周数节点。然后迭代它们:
$weeks = $xp->query( "//*[@class='one']" );
这会从周长的第一个孩子(文本节点)中获取周数。
为新周创建一个数组条目。然后选择该周的潜在工作日节点:
foreach ($weeks as $week) {
$weekNum = $week->firstChild->nodeValue;
$spans = $xp->query( "following::span[@class='one' or @class='two']", $week );
的第二个参数是上下文节点,$xp->query()
轴从该节点开始。
迭代那些:
following::
当你再来一周时,停止:
foreach ($spans as $span) {
否则仔细检查它是否是工作日:
if ($span->getAttribute("class") == "one") break;
然后将新的工作日添加到您的数组中。 要获取表格数据(修正了错误):
if ($span->getAttribute("class") == "two") {
<强>更新强> 要获取表数据,您需要设置更多如上所述的循环。类似的东西:
$table = $xp->query("following-sibling::table[1]", $span->parentNode);
获取表格行。然后用foreach迭代那些,在那些内部,
$rows = $xp->query("tr", $table);
当你遍历单元格时,你的数据将是
$cells = $xp->query("td", $row);
即。子文本节点的文本。请注意,如果 $cell->firstChild->nodeValue
单元格中包含元素,则无法正常工作。
如果您需要有关在PHP中创建和填充数组的帮助,我不是建议您的人,因为我不是PHP开发人员。
注意这都是未经测试的。 HTH。
答案 1 :(得分:0)
使用此输入的其他方法:
<html>
<p>
<span class='one'>week number</span>
</p>
<p>
<span class='two'>day of the week</span>
</p>
<table class='spreadsheet'>
<tr>
<td>Some data</td>
</tr>
</table>
<p>
<span class='two'>another day of the week</span>
</p>
<table class='spreadsheet'>
<tr>
<td>Other data</td>
</tr>
</table>
<p>
<span class='one'>another week number</span>
</p>
</html>
此样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kWeekByNumber" match="span[@class='one']" use="."/>
<xsl:key name="kDayByWeek" match="span[@class='two']"
use="generate-id(preceding::span[@class='one'][1])"/>
<xsl:template match="text()"/>
<xsl:template match="html">
<weeks>
<xsl:apply-templates/>
</weeks>
</xsl:template>
<xsl:template match="span[@class='one']
[count(.|key('kWeekByNumber',.)[1])=1]">
<week number="{.}">
<xsl:apply-templates select="key('kDayByWeek',generate-id())"
mode="days"/>
</week>
</xsl:template>
<xsl:template match="span[@class='two']" mode="days">
<day number="{.}">
<xsl:copy-of select="following::table[1]"/>
</day>
</xsl:template>
</xsl:stylesheet>
输出:
<weeks>
<week number="week number">
<day number="day of the week">
<table class="spreadsheet">
<tr>
<td>Some data</td>
</tr>
</table>
</day>
<day number="another day of the week">
<table class="spreadsheet">
<tr>
<td>Other data</td>
</tr>
</table>
</day>
</week>
<week number="another week number"></week>
</weeks>
注意:也许您可以使用SimpleXML解析该输出以获取数组...