我想检索文档中下一个元素标记的数据,例如:
我想仅为每个不同的范围检索<blockquote> Content 1 </blockquote>
。
<html>
<body>
<span id=12341></span>
<blockquote>Content 1</blockquote>
<blockquote>Content 2</blockquote>
<!-- misc html in between including other spans w/ no relative blockquotes-->
<span id=12342></span>
<blockquote>Content 1</blockquote>
<!-- misc html in between including other spans w/ no relative blockquotes-->
<span id=12343></span>
<blockquote>Content 1</blockquote>
<blockquote>Content 2</blockquote>
<blockquote>Content 3</blockquote>
<blockquote>Content 4</blockquote>
<!-- misc html in between including other spans w/ no relative blockquotes-->
<span id=12344></span>
<blockquote>Content 1</blockquote>
<blockquote>Content 2</blockquote>
<blockquote>Content 3</blockquote>
</body>
</html>
现在我想知道两件事:
1.)如何编写一个匹配的表达式,并且只输出一个紧跟在一个封闭元素(<span></span>
)之后的块引用?
2.)如果我想要,如果我仍然需要在将来输出它们同时仍然适用上一个问题的规则,我怎么能得到内容2,内容3等?
答案 0 :(得分:3)
现在我想知道两件事:
1.)如何编写匹配且仅输出blockquote的表达式 关闭后立即关注 元素(
<span></span>
)?
假设提供的文本转换为格式良好的XML文档(您需要将id
属性的值括在引号中)
使用强>:
/*/*/span/following-sibling::*[1][self::blockquote]
这意味着用英语:选择所有 blockquote
元素,每个元素都是第一个, 跟随的兄弟{ {1}} 元素,它是文档顶部元素的祖母。
2.)如果我想,我怎么能得到内容2,内容3等等 需要输出它们 未来虽然仍然适用于 上一个问题的规则?
是即可。
您可以在span
之后获取所有久负盛名的blockquote
元素:
span
您可以通过获取(N + 1)-st /*/*/span/following-sibling::blockquote
[preceding-sibling::*[not(self::blockquote)][1][self::span]]
之后的一组blockquote
元素:
span
其中/*/*/span/following-sibling::blockquote
[preceding-sibling::*
[not(self::blockquote)][1]
[self::span and count(preceding-sibling::span)=$vN]
]
应由数字N代替。
因此,选择了第一个$vN
之后的blockquote
元素集合:
span
第二个/*/*/span/following-sibling::blockquote
[preceding-sibling::*
[not(self::blockquote)][1]
[self::span and count(preceding-sibling::span)=0]
]
之后的blockquote
元素集合由选择:
span
<强>等即可。 ...
在XPath Visualizer中查看由以下表达式选择的节点:
/*/*/span/following-sibling::blockquote
[preceding-sibling::*
[not(self::blockquote)][1]
[self::span and count(preceding-sibling::span)=1]
]
答案 1 :(得分:0)
简答:将HTML加载到DOMDocument
,然后使用XPath选择所需的节点。
答案很长:
$flag = false; $TEXT = array(); foreach ($body->childNodes as $el) { if ($el->nodeName === '#text') continue; if ($el->nodeName === 'span') { $flag = true; continue; } if ($flag && $el->nodeName === 'blockqoute') { $TEXT[] = $el->firstChild->nodeValue; $flag = false; continue; } }
答案 2 :(得分:0)
请尝试以下*
/html/body/span/following-sibling::*[1][self::blockquote]
匹配任何第一个blockquotes后面的span元素是body的直接子元素或
//span/following-sibling::*[1][self::blockquote]
匹配文档中任意位置的任何第一个块引用
* 编辑:修复Xpath。 Dimitre的积分。我的初始版本将匹配跨度后的任何第一个blockquote,例如它会匹配span p blockquote,这不是你想要的。
以上两者都匹配“内容1”块引用。如果你想匹配跨度后的其他blockquotes(兄弟姐妹,而不是后代),请删除[1]
示例:
$dom = new DOMDocument;
$dom->load('yourFile.xml');
$xp = new DOMXPath($dom);
$query = '/html/body/span/following-sibling::*[1][self::blockquote]';
foreach($xp->query($query) as $blockquote) {
echo $dom->saveXml($blockquote), PHP_EOL;
}
如果你想在没有XPath的情况下这样做,你可以做到
$dom = new DOMDocument;
$dom->preserveWhiteSpace = FALSE;
$dom->load('yourFile.xml');
$body = $dom->getElementsByTagName('body')->item(0);
foreach($body->getElementsByTagName('span') as $span) {
if($span->nextSibling !== NULL &&
$span->nextSibling->nodeName === 'blockquote')
{
echo $dom->saveXml($span->nextSibling), PHP_EOL;
}
}
如果您抓取的HTML不是有效的XHTML,请使用loadHtmlFile()来加载标记。您可以使用libxml_use_internal_errors(TRUE)
和libxml_clear_errors()
来抑制错误。
另请参阅Best methods to parse HTML了解DOM的替代方案(尽管我认为DOM是一个不错的选择)。
答案 3 :(得分:0)
除了@Dimitre good answer之外,您还可以使用:
/html
/body
/blockquote[preceding-sibling::*[not(self::blockquote)][1]
/self::span[@id='12341']]