3

使用空字符串作为值(甚至使用空格)调用 addChild 似乎会导致在节点内添加冗余 SimpleXml 节点,而不是仅添加没有值的节点。

这是发生的事情的快速演示:

[description] => !4jh5jh1uio4jh5ij14j34io5j!

这是一个空字符串:

[description] => SimpleXMLElement Object ( [0] => ) 

我目前使用的解决方法非常糟糕——我正在对最终的 JSON 进行 str_replace 替换!4jh5jh1uio4jh5ij14j34io5j!带有一个空字符串。呸。也许此时唯一的答案是“向 simplexml 提交错误报告”......

有没有人有更好的解决方案?

4

4 回答 4

1

使用 SimpleXML,如果使用 print_r()、var_dump()、serialize() 或类似方法,您得到的结果与对象内部存储的内容不对应。它是一个“神奇”的对象,它重载了 PHP 交互其内容的方式。

您只能使用 AsXML() 获得元素的真实表示。

当诸如 print_r() 之类的东西遍历 SimpleXML 元素或您使用 -> 运算符访问其属性时,您将获得该对象的 munged 版本。这个 munged 版本允许您执行诸如 "echo $xml->surname" 或 $xml->names[1] 之类的操作,就好像它确实具有这些属性一样,但与包含在以下内容中的真正 XML 是分开的:在 munged 表示元素中不一定按顺序排列,名称为 PHP 保留字(如“var”)的元素不会显示为属性,但可以使用 $xml["var"] 之类的代码访问 - 就好像对象是关联数组一样. 在多个同级元素具有相同名称的情况下,它们像数组一样呈现。我猜由于某种原因,空字符串也像数组一样呈现。但是,当使用 AsXML() 输出时,您会得到真实的表示。

于 2009-04-09T04:37:31.917 回答
1

I think I figured out what is going on. Given code like this:

$xml = new SimpleXMLElement('<xml></xml>');
$xml->addChild('node','value');
print_r($xml);

$xml = new SimpleXMLElement('<xml></xml>');
$xml->addChild('node','');
print_r($xml);

$xml = new SimpleXMLElement('<xml></xml>');
$xml->addChild('node');
print_r($xml);

The output is this:

SimpleXMLElement Object
(
    [node] => value
)
SimpleXMLElement Object
(
    [node] => SimpleXMLElement Object
        (
            [0] => 
        )

)
SimpleXMLElement Object
(
    [node] => SimpleXMLElement Object
        (
        )

)

So, to make it so that in case #2 the empty element isn't created (i.e. if you don't know if the second argument is going to be an empty string or not), you could just do something like this:

$mystery_string = '';

$xml = new SimpleXMLElement('<xml></xml>');
if (preg_match('#\S#', $mystery_string)) // Checks for non-whitespace character
  $xml->addChild('node', $mystery_string);
else
  $xml->addChild('node');

print_r($xml);
echo "\nOr in JSON:\n";
echo json_encode($xml);

To output:

SimpleXMLElement Object
(
    [node] => SimpleXMLElement Object
        (
        )

)

Or in JSON:
{"node":{}}

Is that what you want?

Personally, I never use SimpleXML, and not only because of this sort of weird behavior -- it is still under major development and in PHP5 is missing like 2/3 of the methods you need to do DOM manipulation (like deleteChild, replaceChild etc).

I use DOMDocument (which is standardized, fast and feature-complete, since it's an interface to libxml2).

于 2008-11-03T11:10:16.173 回答
0

I've created an Xml library to which extends the simpleXml object to include all of the functionally that is present in the DOMDocument but is missing an interface from SimpleXml (as the two functions interact with the same underlying libxml2 object --by reference). It also has niceties such as AsArray() or AsJson() to output your object in one of those formats.

I've just updated the library to work as you expect when outputting JSON. You can do the following:

$xml = new bXml('<xml></xml>');
$xml->addChild('node', '');
$json_w_root = $xml->asJson(); // is { 'xml': {'node':'' } }
$json = $xml->children()->asJson(); // is { 'node' : '' } as expected.

The library is hosted on google code at http://code.google.com/p/blibrary/

于 2009-01-03T04:53:32.737 回答
0

也许我没有正确理解这个问题,但是在我看来,当您使用 addChild 方法时,无论节点中有什么内容,都需要一个字符串作为节点名称的参数。该值(第二个参数)是可选的,可以留空以添加和清空节点。

让我知道这是否有帮助。

于 2008-10-29T15:57:39.953 回答