我第一次尝试使用XPath - 我正在努力为YQL选择查询找到一个XPath条件,该查询从HTML页面输出顺序不同的兄弟元素。我可以获得所有单独的元素,每个元素都有自己的序列(所以<p1>, <p2>, <p3>
和<ul1>, <ul2>, <ul3>
等),但不是源HTML文档中遇到的序列 - 比如{{1} }。
我目前的最佳状态&#39;是:
<p1> <ul1> <ul2> <ul3> <p2> <p3>
转换为XPath:
select * from html WHERE url = "URL of web page" AND xpath = "//div[@class = \'div class\']/p | //div[@class = \'div class\']/ul"
我可以很容易地用//div[@class = 'div class']/p | //div[@class = 'div class']/ul
这样的文本来获取该文本,但后来我丢失了格式。有没有办法让YQL维护选定的不同元素的序列?或者我只是完全误解了XPath的工作原理?
编辑:示例HTML结构:
//div[@class = 'div class']/text()
我当前的XPath代码(上面)分别返回<div class = "class">
<p>Some text</p>
<p>Following is a list:</p>
<ul>
<li>item1</li>
<li>item2</li>
<li>item3</li>
</ul>
<p>Still more text</p>
</div>
元素和<p>
元素,虽然<ul>
元素是顺序的,但是没有办法确定<p>
元素是(它可以在一个页面之间变化)。因此,我无法从XPath重构HTML。如果我使用<ul>
,则会按从上到下的顺序返回全文,但没有格式化(忽略/text()
和<p>
标记) - 只需一行单个元素之间没有空格的文本。如果<ul>
标记位于<ul>
标记内(后代而不是兄弟),则不会出现问题。该问题仅存在于不同类型的兄弟元素中。
为了复制我所看到的行为,我使用了以下内容:
<p>
答案 0 :(得分:0)
您可能将结果视为XML以外的其他内容。例如,如果您将其视为JSON,则该格式没有预定义的地图顺序。如果您将其视为XML,则订单应该符合预期。
我当前的XPath代码(上面)分别返回
<p>
元素和<ul>
元素
我认为这是yql正在使用的XPath引擎中的一个错误。 XPath语言,它的任何版本,都明确指出在将set与union运算符|
组合后,必须按文档顺序返回元素,这通常与它们在XML中出现的顺序相同< SUP> 1
您可以尝试使用以下XPath修复此错误行为,首先选择所有子项,然后然后过滤器:
//div[@class = 'div class']/*[self::p or self::ul]
我认为这也更容易阅读。
注意:如果引用带双引号的字符串,则不需要使用\'
转义单引号。
1 命名空间和属性节点没有顺序,但顺序必须是稳定的,也就是说,选择相同节点的两个调用将以相同的顺序返回它们。