PHP SimpleXML::addChild 带有空字符串 - 冗余节点

发布于 2024-07-08 06:17:03 字数 440 浏览 4 评论 0原文

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

下面是所发生情况的快速演示:

[description] => !4jh5jh1uio4jh5ij14j34io5j!

这里有一个空字符串:

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

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

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

Calling addChild with an empty string as the value (or even with whitespace) seems to cause a redundant SimpleXml node to be added inside the node instead of adding just the node with no value.

Here's a quick demo of what happens:

[description] => !4jh5jh1uio4jh5ij14j34io5j!

And here's with an empty string:

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

The workaround I'm using at the moment is pretty horrible - I'm doing a str_replace on the final JSON to replace !4jh5jh1uio4jh5ij14j34io5j! with an empty string. Yuck. Perhaps the only answer at this point is 'submit a bug report to simplexml'...

Does anyone have a better solution?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

久夏青 2024-07-15 06:17:03

我想我知道发生了什么事。 给定这样的代码:

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

输出是这样的:

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

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

)

因此,要确保在 #2 的情况下不会创建空元素(即,如果您不知道第二个参数是否为空字符串) ,你可以这样做:

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

输出:

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

)

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

这就是你想要的吗?

就我个人而言,我从不使用 SimpleXML,不仅仅是因为这种奇怪的行为——它仍然处于主要开发阶段,并且在 PHP5 中缺少 2/3 的 DOM 操作所需的方法(例如 deleteChild、replaceChild 等) 。

我使用 DOMDocument(它是标准化、快速且功能完整的,因为它是 libxml2 的接口)。

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).

潜移默化 2024-07-15 06:17:03

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

仅使用 AsXML() 即可获得元素的真实表示。

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

With SimpleXML, what you get if you use print_r(), or var_dump(), serialize(), or similar, does not correspond to what is stored internally in the object. It is a 'magical' object which overloads the way PHP interates its contents.

You get the true representation of the element with AsXML() only.

When something like print_r() iterates over a SimpleXML element or you access its properties using the -> operator, you get a munged version of the object. This munged version allows you to do things like "echo $xml->surname" or $xml->names[1] as if it really had these as properties, but is separate to the true XML contained within: in the munged representation elements are not necessarily in order, and elements whose names are PHP reserved words (like "var") aren't presented as properties, but can be accessed with code like $xml["var"] - as if the object is an associative array. Where multiple sibling elements have the same name they are presented like arrays. I guess an empty string is also presented like an array for some reason. However, when output using AsXML() you get the real representation.

云胡 2024-07-15 06:17:03

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

让我知道这是否有帮助。

Maybe I'm not understanding the question right but, it seems to me that when you use the addChild method, you're required to have a string as an argument for the name of the node regardless of what content is in the node. The value (second argument) is optional and can be left blank to add and empty node.

Let me know if that helps.

坦然微笑 2024-07-15 06:17:03

我创建了一个 Xml 库,它扩展了 simpleXml 对象以包含 DOMDocument 中存在的所有功能,但缺少 SimpleXml 的接口(因为这两个函数通过引用与相同的底层 libxml2 对象交互)。 它还具有 AsArray() 或 AsJson() 等优点,可以以其中一种格式输出对象。

我刚刚更新了该库,以便在输出 JSON 时按照您的预期工作。 您可以执行以下操作:

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

该库托管在 Google 代码上,网址为 http://code.google.com /p/图书馆/

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/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文