【问题标题】:PHP: XML to JSON failsPHP:XML 到 JSON 失败
【发布时间】:2018-01-16 11:40:42
【问题描述】:

当我尝试使用 json_encode 将 XML(simpleXML) 转换为 JSON 时,它适用于没有命名空间的 XML。 例如:

<ebpacket> 
   <head> 
      <packettype> UserAuthorization</packettype>
      <staffcode> UserName  </staffcode> 
      <pwd>  Password  </pwd> 
      <env>  Evnironment  </env> 
   </head> 
</ebpacket>

当我像下面这样用属性转换 XML 时,json_encode 返回一个空的 json:

<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/>
 <soapenv:Header />
 <soapenv:Body>
  <ser:processTrans>
     <xmlValue>
            <ebpacket> 
                <head> 
                    <packettype> UserAuthorization</packettype>
                    <staffcode> UserName  </staffcode> 
                    <pwd> Password  </pwd> 
                    <env>  Evnironment  </env> 
                </head> 
            </ebpacket>
    </xmlValue>
  </ser:processTrans>

我使用的代码块是:

        $xml_str = str_replace(PHP_EOL, '', $xmlstr);
        $xml = simplexml_load_string($xml_str,'SimpleXMLElement',LIBXML_NOCDATA);
        $json_object = json_encode($xml, JSON_PRETTY_PRINT);

【问题讨论】:

  • 尝试使用TRUE 而不是JSON_PRETTY_PRINT,如下所示:secure.php.net/manual/en/book.simplexml.php#105330。但是你也说这是一个SimpleXMLElement,必须根据命名空间进行处理,这就是你有一个空字符串的原因。
  • 后退一步:为什么您要尝试将 XML 转换为 JSON?你真的有一些代码可以通用处理 JSON,但不能以任何方式处理 XML,需要访问整个 XML 文档,没有提前知道结构?或者,您是否需要 XML 中的一些信息,SimpleXML 将帮助您提取这些信息,然后将这些信息转换为 JSON,或者只是转换为 PHP 数组和对象?
  • 但正如 Edwin 所说,您遇到的问题不是属性,而是名称空间。请参阅 stackoverflow.com/questions/44894426/… 了解有关它们是什么以及它们如何与 SimpleXML 一起使用的背景。
  • @IMSoP,我有一个通用的函数,可以把XML转换成JSON,事先不知道XML的结构。
  • @dilani 然后我认为您的函数需要为翻译的工作方式发明自己的约定,因为 SimpleXML 对此的支持非常基本;或者您可以为此任务寻找经过良好测试的第三方库。就个人而言,我认为这样的翻译非常有用。这两种格式可以表示的结构类型差异太大,无法设计适用于所有情况的用户友好映射,并且大多数可以处理一种格式的系统无论如何都可以处理另一种格式。 (我建议使用“翻译”——把它想象成依靠谷歌翻译来本地化你的用户界面)

标签: php json xml xml-parsing simplexml


【解决方案1】:

通读后,我发现您必须注册命名空间才能访问具有命名空间前缀的节点。 例如:

$xml= SimpleXML_Load_String($xml_str,'SimpleXMLElement', LIBXML_NOCDATA, "http://schemas.xmlsoap.org/soap/envelope/");

这将返回一个仅包含 Head 和 Body 的 XML 对象。它将返回具有其他前缀的任何节点。在上面的例子中,它不会返回前缀 'ser' 下的节点。返回的 XML 将是;

<Header></Header>
<Body></Body>

为了能够访问其他节点,你必须使用注册命名空间并查询它。

$xml->registerXPathNamespace('ser', 'http://w3c.soap.envelope.org/');
$result = $xml->xpath('//ser:*');

$result 将是一个包含节点 'ser:processTrans' 下所有属性的数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-12
    • 2018-04-24
    • 2013-09-29
    • 2020-12-06
    • 2020-01-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多