simplexml_load_string 将注释与注释节点混淆

时间:2021-01-04 10:58:01

标签: php xml parsing

我为此搜索了堆栈溢出,并在这里找到了一个类似的旧问题:

Ignore comment node in SimpleXML [duplicate]

不幸的是,在我看来,这本书及其副本都没有回答这个问题。


使用此代码:

        $testXml = <<<XML
        <root>
          <comment>this comment is part of my payload and should be parsed</comment>
          <node>
          </node>
          <!-- this comment should not be parsed-->
        </root>
        XML;

        xmlDataTest = simplexml_load_string($testXml);
        var_dump($xmlDataTest);

我明白了:

object(SimpleXMLElement)#401 (2) {
  ["comment"]=>
  array(2) {
    [0]=>
    string(29) "this comment is part of my payload and should be parsed"
    [1]=>
    object(SimpleXMLElement)#403 (0) {
    }
  }
  ["node"]=>
  object(SimpleXMLElement)#402 (0) {
  }
}

但我希望注释掉的内容被完全忽略:

object(SimpleXMLElement)#401 (2) {
  ["comment"]=>
  string(55) "this comment is part of my payload and should be parsed"
  ["node"]=>
  object(SimpleXMLElement)#402 (0) {
  }
}

有人知道如何让 simplexml_load_string 忽略第二条评论吗?

根据有关 var_dump 相关性的评论进行编辑。

如果我想快速从 XML 转换为 JSON,我可以这样做:

$json = json_encode(simplexml_load_string($testXml), JSON_PRETTY_PRINT);

此外,根据是否有人在我的 XML 中添加了注释,我得到了不同的 JSON。我要么变得漂亮干净:

{
    "comment": "this comment is part of my payload and should be parsed",
    "node": {}
}

或丑陋:

{
    "comment": [
        "this comment is part of my payload and should be parsed",
        {}
    ],
    "node": {}
}

我仍然觉得评论改变 simplexml_load_string 的行为是非常糟糕的,尽管我知道你们中的一些人会不同意。无论如何我可以处理它,我感谢大家到目前为止的好评(我会分配一些赞成票)

1 个答案:

答案 0 :(得分:2)

这只是一个调试输出。如果您访问该值,评论将被忽略:

$root = simplexml_load_string($testXml);
var_dump((string)$root->comment);

foreach ($root->comment as $element) {
    var_dump((string)$element);
}

输出:

string(55) "this comment is part of my payload and should be parsed"
string(55) "this comment is part of my payload and should be parsed"

然而,如果你想要明确,你可以切换到 DOM+Xpath。它允许特定的节点处理。

$document = new DOMDocument();
$document->loadXML($testXml);
$xpath = new DOMXpath($document);

var_dump(
    [
        'element node' => $xpath->evaluate('string(/root/comment)'),
        'comment node' => $xpath->evaluate('string(/root/comment())')
    ]
);

输出:

array(2) {
  ["element node"]=>
  string(55) "this comment is part of my payload and should be parsed"
  ["comment node"]=>
  string(34) " this comment should not be parsed"
}