【问题标题】:Pulling both the text and attribute of a given node using Xpath使用 Xpath 拉取给定节点的文本和属性
【发布时间】:2010-09-13 14:29:24
【问题描述】:

我正在使用 PHP 和 xpath 解析来自 API 调用的 XML 结果。

 $dom = new DOMDocument();
 $dom->loadXML($response->getBody());

 $xpath = new DOMXPath($dom);
 $xpath->registerNamespace("a", "http://www.example.com");

 $hrefs = $xpath->query('//a:Books/text()', $dom);

 for ($i = 0; $i < $hrefs->length; $i++) {
      $arrBookTitle[$i] = $hrefs->item($i)->data;
 }

 $hrefs = $xpath->query('//a:Books', $dom);

 for ($i = 0; $i < $hrefs->length; $i++) {
      $arrBookDewey[$i] = $hrefs->item($i)->getAttribute('DeweyDecimal');
 }

这可行,但有没有一种方法可以从一个查询中同时访问文本和属性?如果是这样,一旦执行查询,您如何获得这些项目?

【问题讨论】:

    标签: php dom xpath


    【解决方案1】:

    你能查询连接吗?

    $xpath->query('concat(//a:Books/text(), //a:Books/@DeweyDecimal)', $dom);
    

    XSLT 本身就是一种表达式语言,您可以从表达式中构造您想要的任何特定格式的返回值。

    【讨论】:

    • 那我就直接用item->data和item->getAttribute来拉取结果了吗?
    • 我不确定 PHP 的 XSLT 库是如何工作的,但您可以只使用 item->data 来获取它。无论如何,值得一试。
    【解决方案2】:

    环顾四周后,我发现了这个解决方案。这样我可以获取元素文本并访问节点的任何属性。

    $hrefs = $xpath->query('//a:Books', $dom);
    
    for ($i = 0; $i < $hrefs->length; $i++) {
        $arrBookTitle[$i] = $hrefs->item($i)->nodeValue;
        $arrBookDewey[$i] = $hrefs->item($i)->getAttribute('DeweyDecimal');
    }
    

    【讨论】:

      【解决方案3】:

      如果您只是从 XML 文档中检索值,SimpleXML 可能是更精简、更快且内存友好的解决方案:

      $xml=simplexml_load_string($response->getBody());
      $xml->registerXPathNamespace('a', 'http://www.example.com');
      $books=$xml->xpath('//a:Books');
      foreach ($books as $i => $book) {
          $arrBookTitle[$i]=(string)$book;
          $arrBookDewey[$i]=$book['DeweyDecimal'];
      }
      

      【讨论】:

        【解决方案4】:

        将选择“a:Books”的文本节点及其“DeweyDecimal”属性的单个 XPath 表达式如下

        //a:Books/text() | //a:Books/@DeweyDecimal

        请注意在上面的表达式中使用了 XPath 的联合运算符。

        另一个注意事项:尽量避免使用“//”缩写,因为它可能会导致整个 XML 文档被遍历,因此非常昂贵。当 XML 文档的结构已知时,建议始终使用更具体的 XPath 表达式(例如由一系列特定位置步骤组成)。

        【讨论】:

          猜你喜欢
          • 2023-01-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-04-26
          相关资源
          最近更新 更多