XPath查询多个选择器

时间:2012-01-29 17:04:13

标签: php regex xpath

我想从选择器中获取值和属性 然后根据查询获取子项的属性和值。

请允许我举一个例子。

这是结构

<div class='message'>
   <div>
   <a href='http://www.whatever.com'>Text</a>
   </div>

   <div>
    <img src='image_link.jpg' />
   </div>

</div>

<div class='message'>
   <div>
   <a href='http://www.whatever2.com'>Text2</a>
   </div>

   <div>
    <img src='image_link2.jpg' />
   </div>

</div>

所以我想做一个查询以匹配所有这些。

这样的事情:

 //$dom is the DomDocument() set up after loaded HTML with $dom->loadHTML($html);
$dom_xpath = new DOMXpath($dom);
$elements = $dom_xpath->query('//div[@class="message"], //div[@class="message"] //a, //div[@class="message"] //img');

foreach($elements as $ele){
   echo $ele[0]->getAttribute('class'); //it should return 'message'
   echo $ele[1]->getAttribute('href'); //it should return 'http://www.whatever.com' in the 1st loop, and 'http://www.whatever2.com' in the second loop
   echo $ele[2]->getAttribute('src'); //it should return image_link.jpg in the 1st loop and 'image_link2.jpg' in the second loop
}

有没有像我在示例中那样使用多个xpath选择器的方法呢?避免一直查询并节省一些CPU。

2 个答案:

答案 0 :(得分:6)

在单个表达式中使用union运算符(|),如下所示:

//div[@class="message"]|//div[@class="message"]//a|//div[@class="message"]//img

请注意,这将返回一个展平的结果集(可以这么说)。换句话说,您不会像示例节目那样以三个为一组访问元素。相反,您只需迭代表达式匹配的所有内容(按文档顺序)。出于这个原因,简单地迭代//div[@class="message"]返回的节点并使用DOM方法访问其子节点(对于其他元素)可能更聪明。

答案 1 :(得分:3)

使用

(//div[@class='message'])[$k]//@*

这将选择div属性具有字符串值class

的文档中属于第k个"message"(及其任何后代)的所有三个属性

您可以评估N此类XPath表达式 - {1}}从1到$k,其中NN的总数

基于XSLT的验证

//div[@class='message']

将此转换应用于提供的XML文档(包装在单个顶部元素中以形成格式良好):

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:for-each select="//div[@class='message']">
    <xsl:variable name="vPos" select="position()"/>

    <xsl:apply-templates select=
    "(//div[@class='message'])[0+$vPos]//@*"/>
 ================
  </xsl:for-each>
 </xsl:template>

 <xsl:template match="@*">
  <xsl:value-of select=
  "concat('name = ', name(), ' value = ', ., '&#xA;')"/>
 </xsl:template>
</xsl:stylesheet>

XPath表达式被评估两次,所选属性被格式化并输出

<html>
    <div class='message'>
        <div>
            <a href='http://www.whatever.com'>Text</a>
        </div>
        <div>
            <img src='image_link.jpg' />
        </div>
    </div>
    <div class='message'>
        <div>
            <a href='http://www.whatever2.com'>Text2</a>
        </div>
        <div>
            <img src='image_link2.jpg' />
        </div>
    </div>
</html>