Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/236.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将具有多个命名空间的XML解析为JSON-PHP_Php_Xml_Xpath_Simplexml - Fatal编程技术网

将具有多个命名空间的XML解析为JSON-PHP

将具有多个命名空间的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并将其解析为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: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/*'));