将具有多个命名空间的XML解析为JSON-PHP
我想访问XML并将其解析为JSON将具有多个命名空间的XML解析为JSON-PHP,php,xml,xpath,simplexml,Php,Xml,Xpath,Simplexml,我想访问XML并将其解析为JSON <?xml version='1.0' encoding='UTF-8'?> <soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:ser='http://service.billing.org/'> <soapenv:Header /> <soapenv:Body> <ser:proc
<?xml version='1.0' encoding='UTF-8'?>
<soapenv:Envelope xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:ser='http://service.billing.org/'>
<soapenv:Header />
<soapenv:Body>
<ser:processTrans>
<xmlValue>
<![CDATA[
<ebpacket>
<head>
<packettype> UserAuthorization</packettype>
<staffcode> ePay_UserName </staffcode>
<pwd> ePay_Password </pwd>
</head>
<body>
<email> _username </email>
<loginpwd> _password </loginpwd>
<deviceid> DeviceId </deviceid>
</body>
</ebpacket>
]]>
</xmlValue>
</ser:processTrans>
问题是,XML结构事先不知道。因此,我无法通过名称空间专门访问。除非我指定名称空间$xml->xpath('//soapenv:Body'),否则它不会返回预期的结果。我认为您混淆了两个名称空间,试图用
ser
使用的URI注册soapenv
前缀。这并不是说它会影响代码,但它可能不会给出您期望的结果
至于事先不知道名称空间,在SimpleXML中,您可以使用getDocNamespaces()
从文档中获取名称空间,然后循环并根据前缀注册它们。下面的代码获取主体的XML内容
$xml_str = str_replace(PHP_EOL, '', $xmlstr);
$xml = simplexml_load_string($xml_str,'SimpleXMLElement', LIBXML_NOCDATA);
$ns = $xml->getDocNamespaces(true);
foreach ( $ns as $prefix => $URI ) {
$xml->registerXPathNamespace($prefix, $URI);
}
$j_obj = json_encode($xml->xpath('//soapenv:Body/*'));
你试过使用dom吗?您可以从domdocument获取名称空间,并执行遍历文档所需的相同操作,查看每一级别的可用名称空间(因为前缀可以在任何节点上重新定义),并决定如何在JSON中表示它们(包括名称空间URI将是最正确的,因为前缀可以任意更改)。你可能会从“对不起”的实施中得到一些线索,这是我在问题中犯的一个错误。我已经编辑过了。如果我不想在代码中提及**'//ser:processTrans'**的话,它就不会这样工作,因为XML的结构是动态的。我已经更新了xpath表达式,你能试试吗。上面的方法很有效。但是,是否有一种仅通过“前缀”访问元素的方法?例如,只要使用“soapenv”而不是“soapenv:Body”,就可以执行类似于
$xml->xpath('//soapenv:')的操作代码>,它搜索带有该前缀的所有元素-在示例XML中,它将找到3-soapenv:Envelope、soapenv:Header和soapenv:Body。
$xml_str = str_replace(PHP_EOL, '', $xmlstr);
$xml = simplexml_load_string($xml_str,'SimpleXMLElement', LIBXML_NOCDATA);
$ns = $xml->getDocNamespaces(true);
foreach ( $ns as $prefix => $URI ) {
$xml->registerXPathNamespace($prefix, $URI);
}
$j_obj = json_encode($xml->xpath('//soapenv:Body/*'));