【问题标题】:Forcing a SimpleXML Object to a string, regardless of context将 SimpleXML 对象强制为字符串,无论上下文如何
【发布时间】:2010-09-29 19:33:23
【问题描述】:

假设我有一些这样的 XML

<channel>
  <item>
    <title>This is title 1</title>
  </item>
</channel>

下面的代码做了我想要的,它将标题作为字符串输出

$xml = simplexml_load_string($xmlstring);
echo $xml->channel->item->title;

这是我的问题。下面的代码在该上下文中不将标题视为字符串,因此我最终在数组中使用 SimpleXML 对象而不是字符串。

$foo = array( $xml->channel->item->title );

我一直在这样解决它

$foo = array( sprintf("%s",$xml->channel->item->title) );

但这看起来很难看。

无论上下文如何,将 SimpleXML 对象强制为字符串的最佳方法是什么?

【问题讨论】:

  • 我已经向 PHP 提交了多个请求,以为此实现类似于 SOAP_SINGLE_ELEMENT_ARRAYS 的东西,并鼓励其他人也这样做。 SOAP_SINGLE_ELEMENT_ARRAYS 强制 / 可能 / 包含多个字符串的元素始终被解析为字符串。当然,正如其他人提到的,你需要知道你得到了什么,但是我一次又一次地遇到了 .NET SOAP 服务器的问题,WSDL (通过 .NET 的“魔术”默认值)将每个字符串原型化为混合或字符串数​​组。而不是 current()'ing 或 typecasting,该位只返回一个字符串

标签: php xml simplexml


【解决方案1】:

将 SimpleXMLObject 类型转换为字符串:

$foo = array( (string) $xml->channel->item->title );

上面的代码内部调用了SimpleXMLObject 上的__toString()。此方法不公开,因为它会干扰 SimpleXMLObject 的映射方案,但仍可以通过上述方式调用。

【讨论】:

  • 这比使用 sprintf 更干净。我喜欢它
  • 请注意,使用接受字符串参数的函数将自动进行这种类型转换(例如 echo、str_replace、substr)。
  • $foo = (string) $xml->channel->item->title;是我一直在寻找的,因为我不需要数组。谢谢。
  • +100 你刚刚度过了我的夜晚!我是 SimpleXMLObject 的新手,我从中提取的变量在屏幕上“打印”得很好,但我的数据库查询失败了……叹息!从什么时候开始 PHP 是严格类型的? ;-)
  • @megaSteve4 "PHP 是从什么时候开始严格输入类型的?" - 正是因为这不是需要发生的:大多数函数没有定义的类型上下文,因此不能隐式转换为该类型。当然,他们可以显式地转换他们的输入参数,这就是substr 等人工作的原因。不过,越早进行强制转换越安全,所以您知道所有函数都会看到他们期望的数据。
【解决方案2】:

可以使用PHP函数

strval();

此函数返回传递给它的参数的字符串值。

【讨论】:

  • @Mark Biek:它确实适用于实现了__toString() 的对象,特别是在这个问题的情况下,它非常适用于SimpleXMLElement 类型的对象。您可以将其与接受的答案中的string 进行比较。 strval() 是一个方便的回调函数,通常与 array_map()iterator_to_array($simpleXMLElement, false)SimpleXMLElement::xpath() 结合使用。
【解决方案3】:

有原生的SimpleXML方法SimpleXMLElement::asXML 根据参数,它将 SimpleXMLElement 写入 xml 1.0 文件或仅写入字符串:

$xml = new SimpleXMLElement($string);
$validfilename = '/temp/mylist.xml';
$xml->asXML($validfilename);    // to a file
echo $xml->asXML();             // to a string

【讨论】:

  • 我调用了一个未定义的函数 asXML,所以我猜这已经过时了?
  • @Eoin 嗯...刚刚测试了我的示例,它仍然适用于原生 php 7.3 安装
  • 我一定遇到了不同的问题。我很抱歉。我现在解决了我的问题:)
【解决方案4】:

另一种丑陋的做法:

$foo = array( $xml->channel->item->title."" );

它有效,但它并不漂亮。

【讨论】:

    【解决方案5】:

    接受的答案实际上返回一个包含字符串的数组,这不是 OP 所要求的(字符串)。 要扩展该答案,请使用:

    $foo = [ (string) $xml->channel->item->title ][0];
    

    返回数组的单个元素,一个字符串。

    【讨论】:

      【解决方案6】:

      要将 XML 数据放入 php 数组中,请执行以下操作:

      // this gets all the outer levels into an associative php array
      $header = array();
      foreach($xml->children() as $child)
      {
        $header[$child->getName()] = sprintf("%s", $child); 
      }
      echo "<pre>\n";
      print_r($header);
      echo "</pre>";
      

      要得到一个孩子,然后这样做:

      $data = array();
      foreach($xml->data->children() as $child)
      {
        $header[$child->getName()] = sprintf("%s", $child); 
      }
      echo "<pre>\n";
      print_r($data);
      echo "</pre>";
      

      您可以通过每个级别扩展 $xml-> 直到获得您想要的 您还可以将所有节点放入一个数组中,而无需级别或 几乎任何其他你想要的方式。

      【讨论】:

        【解决方案7】:

        试试 strval($xml->channel->item->title)

        【讨论】:

          【解决方案8】:

          不确定他们是否改变了 __toString() 方法的可见性,因为接受的答案已经写好了,但目前它对我来说很好:

          var_dump($xml->channel->item->title->__toString());
          

          输出:

          string(15) "This is title 1"
          

          【讨论】:

            【解决方案9】:

            有本机 SimpleXML 方法 SimpleXMLElement::asXML 根据参数,它将 SimpleXMLElement 写入 xml 1.0 文件,是的

            $get_file= read file from path;
            $itrate1=$get_file->node;
            $html  = $itrate1->richcontent->html;
            
            
            echo  $itrate1->richcontent->html->body->asXML();
             print_r((string) $itrate1->richcontent->html->body->asXML());
            

            【讨论】:

              【解决方案10】:

              只要把''。在任何变量之前,它将转换为字符串。

              $foo = array(''.$xml->channel->item->title);

              【讨论】:

                【解决方案11】:

                以下是一个递归函数,它将所有单子元素类型转换为String

                //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                // FUNCTION - CLEAN SIMPLE XML OBJECT
                //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
                function cleanSimpleXML($xmlObject = ''){
                
                    // LOOP CHILDREN
                    foreach ($xmlObject->children() as $child) {
                
                        // IF CONTAINS MULTIPLE CHILDREN
                        if(count($child->children()) > 1 ){
                
                            // RECURSE
                            $child = cleanSimpleXML($child);
                
                        }else{
                
                            // CAST
                            $child = (string)$child;
                
                        }
                
                    }
                
                    // RETURN CLEAN OBJECT
                    return $xmlObject;
                
                } // END FUNCTION
                

                【讨论】:

                  猜你喜欢
                  • 2011-01-02
                  • 2017-08-02
                  • 1970-01-01
                  • 2020-04-02
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多