【问题标题】:Using xPath to access values of simpleXML使用 xPath 访问 simpleXML 的值
【发布时间】:2014-07-29 21:15:57
【问题描述】:

我的数据库中有一个 XML 对象结果,其中包含设置。

我正在尝试访问特定 settingName 的值:

    SimpleXMLElement Object
(
[settings] => Array
    (
        [0] => SimpleXMLElement Object
            (
                [settingName] => Test
                [settingDescription] => Testing
                [requireValue] => 1
                [localeID] => 14
                [status] => 1
                [value] => 66
                [settingID] => 5
            )

        [1] => SimpleXMLElement Object
            (
                [settingName] => Home Page Stats
                [settingDescription] => Show the Top 5 Teammate / Teamleader stats?
                [requireValue] => 0
                [localeID] => 14
                [status] => 0
                [value] => SimpleXMLElement Object
                    (
                    )

                [settingID] => 3
            )

    )

)

我尝试使用 xPath 并且到目前为止:

$value = $fetchSettings->xpath("//settingName[text()='Test']/../value");

返回:

Array ( [0] => SimpleXMLElement Object ( [0] => 66 ) )

如何获取实际值而不仅仅是另一个数组/对象?

对于上面的示例,最终结果将只是 66

【问题讨论】:

  • 使用不错的 PHP 版本:$value = (string) reset($fetchSettings->xpath("//settingName[text()='Test']/../value")); - 如果没有结果,将给出一个零长度的字符串,否则将始终返回第一个结果节点(按文档顺序)。

标签: php xml xpath simplexml


【解决方案1】:
  1. SimpleXMLElement::xpath() 返回“搜索结果”的普通 PHP 数组;第一个结果将始终是索引0如果找到任何结果
  2. 每个“搜索结果”都是一个SimpleXMLElement 对象,它有一个神奇的__toString() 方法来获取节点的直接文本内容(包括CDATA,但包括子节点内的文本等)。最简单的调用方式是使用(string)$my_element(int)$my_element 也会调用它,然后将结果转换为整数。

所以:

 $xpath_results = $fetchSettings->xpath("//settingName[text()='Test']/../value");
 if ( count($xpath_results) > 0 ) {
      $value = (string)$xpath_results[0];
 }

另外,the DOMXPath class 可以返回元素和属性节点以外的结果,因为 DOM 具有更丰富的对象模型。例如,您可以使用以 //text() 结尾的 XPath 表达式来引用节点的文本内容,而不是节点本身(SimpleXML 会进行搜索,但无论如何都会给您一个元素对象)。

缺点是使用起来比较冗长,但幸运的是,您可以混合和匹配两组函数(使用 dom_import_simplexml() 及其对应项),因为它们具有相同的底层表示:

 // WARNING: Untested code. Please comment or edit if you find a bug!
 $fetchSettings_dom = dom_import_simplexml($fetchSettings);
 $xpath = new DOMXPath($fetchSettings_dom->ownerDocument);
 $value = $xpath->evaluate(
      "//settingName[text()='Test']/../value/text()",
      $fetchSettings_dom
 );

【讨论】:

    【解决方案2】:

    因为 XML 文件中的每个元素都可以多次出现,所以解析器总是返回一个数组。如果您确定,它只是您可以使用的单个项目current()

    echo (string) current($value);
    

    请注意,我将 SimpleXMLElement 转换为字符串(请参阅 http://php.net/manual/simplexmlelement.tostring.php )以获取实际值。

    【讨论】:

      【解决方案3】:

      改用 DomXPath 类。 http://php.net/manual/en/domxpath.evaluate.php 来自 php.net 的示例与您想要实现的相同:

      <?php
      $doc = new DOMDocument;
      $doc->load('book.xml');
      $xpath = new DOMXPath($doc);
      $tbody = $doc->getElementsByTagName('tbody')->item(0);
      // our query is relative to the tbody node
      $query = 'count(row/entry[. = "en"])';
      $entries = $xpath->evaluate($query, $tbody);
      echo "There are $entries english books\n";
      

      通过这种方式,您可以直接从 XML 中获取值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-11-30
        • 1970-01-01
        • 1970-01-01
        • 2021-06-06
        • 2020-01-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多