【问题标题】:PHP SimpleXML::addChild with empty string - redundant node带有空字符串的 PHP SimpleXML::addChild - 冗余节点
【发布时间】:2010-09-19 19:48:50
【问题描述】:

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

这里是发生了什么的快速演示:

[description] => !4jh5jh1uio4jh5ij14j34io5j!

这里是一个空字符串:

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

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

谁有更好的解决方案?

【问题讨论】:

    标签: php simplexml addchild


    【解决方案1】:

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

    如果有帮助,请告诉我。

    【讨论】:

      【解决方案2】:

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

      $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 的接口)。

      【讨论】:

        【解决方案3】:

        我创建了一个 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.
        

        该库托管在谷歌代码http://code.google.com/p/blibrary/

        【讨论】:

        • 诀窍是在 JSON 编码之前将 simpleXML 对象转换为数组。
        【解决方案4】:

        对于 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() 输出时,您会得到真实的表示。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-06-30
          • 2011-06-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-06-14
          • 1970-01-01
          • 2011-04-13
          相关资源
          最近更新 更多