首页 > 解决方案 > simplexml_load_string 将注释与注释节点混淆

问题描述

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

忽略 SimpleXML 中的注释节点 [重复]

不幸的是,在我看来,这和它的重复都没有回答这个问题。


使用此代码:

        $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);

同样在这里,我会得到不同的 JSON,具体取决于是否有人在我的 XML 中添加了评论。我要么变得又好又干净:

{
    "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,尽管我知道你们中的一些人会不同意。无论如何我可以处理它,我感谢大家迄今为止的好评(我会分配一些upvotes)

标签: phpxmlparsing

解决方案


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

$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"
}

推荐阅读