ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

php – 如何检索相对于特定找到的HTML节点的父元素文本?

2019-06-28 19:17:13  阅读:118  来源: 互联网

标签:php css-selectors xpath


我正在编写一个可以执行操作列表的通用HTML资源管理器,例如访问页面,查找表,查找行,存储数据等.它在内部使用Goutte / Guzzle,因此可以使用CSS和XPath选择器.我有一个有趣的问题,我坚持选择相对于现有结果集的一组新结果.

考虑这个演示HTML:

    <h2>Burrowing</h2>
    <ul>
        <li>
            <a href="/jobs/junior-mole">Junior Mole</a>
        </li>
        <li>
            <a href="/jobs/head-of-badger-partnerships">Head of Badger Partnerships</a>
        </li>
        <li>
            <a href="/jobs/trainee-worm">Trainee Worm</a>
        </li>
    </ul>

    <h2>Tree Surgery</h2>
    <ul>
        <li>
            <a href="/jobs/senior-woodpecker">Senior Woodpecker</a>
        </li>
        <li>
            <a href="/jobs/owl-supervisor">Owl Supervisor</a>
        </li>
    </ul>

    <h2>Grass maintenance</h2>
    <ul>
        <li>
            <a href="/jobs/trainee-sheep">Trainee sheep</a>
        </li>
        <li>
            <a href="/jobs/sheep-shearer">Sheep shearer</a>
        </li>
    </ul>

    <h2>Aerial supervision</h2>
    <ul>
        <li>
            <a href="/jobs/head-magpie-ops">Head of Magpie Operations</a>
        </li>
    </ul>

我运行这个CSS查询来获取链接中的角色(这正确地获得了八个项目):

ul li a

对于每一个,我想得到类别,即< h2>紧接在< ul>之前在每种情况下.现在我可以用绝对的CSS选择器来做到这一点:

h2

然而,这得到了四个结果,所以我不知道哪个类别(h2)与哪个作业(链接)有关.我需要获得8个结果:第一个类别的三个,第二个中的两个,第三个中的两个,以及第四个中的一个,因此每个类别映射到每个角色.

我想知道我是否需要一个父选择器,所以我从CSS切换到XPath,并首先尝试这个,它让每个h2有一个紧接着的列表项:

//h2[(following-sibling::ul)[1]/li/a]

这发现h2s具有指定的父结构,但又返回了四个结果 – 没有好处.

下一次尝试:

//ul/li[../preceding-sibling::h2[1]]

获得正确数量的结果(基于获取具有紧接在前标题的列表项)但获取链接文本,而不是类别文本.

我想做一个循环 – 我知道我有八个结果,所以我可以这样做(X是一个从1到8循环的注入变量).这是有效的,但我认为在这里添加一个手动循环相当不优雅 – 我试图让我的规则尽可能通用:

//li[X]/../preceding-sibling::h2[1]

是否有可以返回所需结果的XPath操作?为避免疑问,我正在寻找以下内容(或只是文本元素会很好):

<h2>Burrowing</h2>
<h2>Burrowing</h2>
<h2>Burrowing</h2>
<h2>Tree Surgery</h2>
<h2>Tree Surgery</h2>
<h2>Grass maintenance</h2>
<h2>Grass maintenance</h2>
<h2>Aerial supervision</h2>

CSS也没关系,但我认为这是不可能的,因为CSS没有父运算符(在任何情况下,Goutte只是将CSS选择器转换为XPath选择器).

由于我使用的是PHP(5.5),我相信我必须坚持使用XPath 1.0.

解决方法:

不,没有单个XPath 1.0表达式可以返回您想要的内容.首先是因为XPath 1.0不允许迭代中间结果,其次因为一系列项目是defined as a node-set – 其中没有重复项.

我可以看到两个可能的问题解决方案.编写PHP代码

>首先检索所有相关的节点,例如用@ a表达式
>依次对每个表达式应用第二个XPath表达式:preceding :: h2 [1]

鉴于我的技能很差,你必须自己编写PHP代码.但我可以提供一个替代方案:你也可以在PHP中使用XSLT 1.0转换,there are XSLT 1.0 processors.

样式表

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />

    <xsl:template match="/">
      <xsl:for-each select="//a">
          <xsl:copy-of select="preceding::h2[1]"/>
      </xsl:for-each>
    </xsl:template>

</xsl:transform>

应用于您的输入(添加根元素后),结果是

<h2>Burrowing</h2>
<h2>Burrowing</h2>
<h2>Burrowing</h2>
<h2>Tree Surgery</h2>
<h2>Tree Surgery</h2>
<h2>Grass maintenance</h2>
<h2>Grass maintenance</h2>
<h2>Aerial supervision</h2>

在线尝试here.顺便说一句,如果您对如何使用XPath 2.0感兴趣,正如您在评论中提到的,请参阅this version instead

for $a in //a return $a/preceding::h2[1]

标签:php,css-selectors,xpath
来源: https://codeday.me/bug/20190628/1318694.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有