XPath查询多个选择器


XPath to query multiple selectors

我想从选择器中获取值和属性然后基于查询获取其子级的属性和值。

请允许我举一个例子。

这就是的结构

<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。

在如下的单个表达式中使用并集运算符(|):

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

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

使用

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

这将选择属于文档中class属性具有字符串值"message" 的第$k个div(及其任何子代)的所有三个属性

您可以计算N这样的XPath表达式——对于从1到N$k,其中N//div[@class='message'] 的总数

基于XSLT的验证

<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>

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

<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>

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

name = class value = message
name = href value = http://www.whatever.com
name = src value = image_link.jpg
 ================
name = class value = message
name = href value = http://www.whatever2.com
name = src value = image_link2.jpg
 ================