【问题标题】:How to get all node values from a feed如何从提要中获取所有节点值
【发布时间】:2012-12-19 08:01:17
【问题描述】:

我有以下提要:

$result = apiCall('somevalue', 'somevalue', array('somevalue' => $some_string));

json 格式。我可以很容易地用

把它变成 xml
$xml = simplexml_load_string($result);

xml 提要如下所示:

<?xml version="1.0" encoding="ISO-8859-15"?>
    <response>
        <status>success</status>
        <code>200</code>
        <message>
            <a>
                <g>val1</g>
                <b>val2</b>
                <c>val3</c>
            </a>
            <d>
                <e>val4</e>
                <f>val5</f>
            </d>
        </message>
    </response>

有没有一种简单快捷的方法来获取所有节点值(即 val1、val2、val3、val4、val5 等)?

【问题讨论】:

标签: php xml json simplexml


【解决方案1】:

我写了一些我认为可行的东西:

<?php

$xml = <<<EOD
<?xml version="1.0" encoding="ISO-8859-15"?>
<response>
    <status>success</status>
    <code>200</code>
    <message>
        <a>
            <g>val1</g>
            <b>val2</b>
            <c>val3</c>
        </a>
        <d>
            <e>val4</e>
            <f>val5</f>
        </d>
    </message>
</response>
EOD;

$output = array();
$test = simplexml_load_string($xml);
$result = $test->xpath('message//*[not(*)]');
while(list(, $node) = each($result)) {
    array_push($output, (string) $node);
}

var_dump($output);

?>

我还没有在很多东西(属性)上测试它,但是在提供的输入上它给出了预期的输出。 它的作用就像您可以看到一个 xpath 表达式,该表达式检索 message 节点的任何子节点。

当然,因为其中也有包含更多子节点的节点(例如ad),我们需要将它们过滤掉。所以包含not(*)的最后一部分意味着它只会选择那些没有任何子孩子的孩子。

我不是 XPATH 专家,所以可能有更快的方法来实现这一点,但我认为这样就可以了。

【讨论】:

  • Dimitri,而不是 var_dump($output) 使用以下代码:for ($i = 0; $i &lt; count($output); $i++) { $key=key($output); $val=$output[$key]; if ($val&lt;&gt; ' ') { echo $val ." &lt;br&gt; "; } next($output); } 给我我需要的 - 所有节点值。 var_dump($output); 输出数组 array(50) { [0]=&gt; string(7) "value1" [1]=&gt; string(16) 等。
  • var_dump($output); 显然只是一个转储内容的测试用例(因此您和我可以看到结果并验证它是否有效)。实现(以及您对输出的操作)显然是您的任务,而不是我的任务。 :) 真正的解析工作在上面的几行中完成。
  • 是的,如果你想根据它们的键将特定变量分配给值,你的方法会更好。
  • 我认为您不理解所提供的代码。 var_dump($output); 或您的输出对您如何解析此 XML 的问题没有任何影响。上面的while(list(, $node) = each($result)) { ... }已经解析好了。
【解决方案2】:

我得出了与 Dimitri M 类似的结论,它基于之前的问答How to select all leaf nodes using XPath expression?

叶节点是最外层的节点,也就是您要查找的节点,这里是 text() 节点。

$nodeValues = array_map(
    'trim',
    simplexml_load_string($xml)->xpath('message//*[not(*)]/text()')
);

鉴于$xml 是您的XML 输入,$nodeValues 是所有代表您正在寻找的节点值的字符串的数组。示例:

Array
(
    [0] => val1
    [1] => val2
    [2] => val3
    [3] => val4
    [4] => val5
)

【讨论】:

  • 注意:与相关 XML 的其他答案相比,这会返回相同的结果。我也在array_map 操作中通过trim 在此处“cast”。所以我也有转换为字符串。您需要使用 SimpleXML 获取具体的字符串值。
  • 我刚发帖就注意到了。我的借口。 ^^
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-15
  • 1970-01-01
  • 2020-09-02
  • 1970-01-01
  • 2012-05-05
相关资源
最近更新 更多