我花了两天时间尝试将XML转换为json,但是没有运气。
我尝试了常规的simplexml_load_string
,XMLReader
和SimpleXMLElement
当SearchResults只有一项时,我可以使用XMLReader读取数据。但是当返回多个项目时,我不确定该怎么办。
```
<?xml version="1.0" encoding="utf-8"?>
<DataSet xmlns="http://exampleurl.com/">
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="SearchResults">
<xs:complexType>
<xs:sequence>
<xs:element name="VehicleID" type="xs:long" minOccurs="0" />
<xs:element name="make" type="xs:string" minOccurs="0" />
<xs:element name="model" type="xs:string" minOccurs="0" />
<xs:element name="series" type="xs:string" minOccurs="0" />
<xs:element name="engine" type="xs:string" minOccurs="0" />
<xs:element name="yearrange" type="xs:string" minOccurs="0" />
<xs:element name="details" type="xs:string" minOccurs="0" />
<xs:element name="chassis" type="xs:string" minOccurs="0" />
<xs:element name="Countryoforigin" type="xs:string" minOccurs="0" />
<xs:element name="VIN" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="ChargeDetails">
<xs:complexType>
<xs:sequence>
<xs:element name="ChargeApplies" type="xs:long" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="vehicleRawDetails">
<xs:complexType>
<xs:sequence>
<xs:element name="licenceplate" type="xs:string" minOccurs="0" />
<xs:element name="VIN" type="xs:string" minOccurs="0" />
<xs:element name="make" type="xs:string" minOccurs="0" />
<xs:element name="model" type="xs:string" minOccurs="0" />
<xs:element name="submodel" type="xs:string" minOccurs="0" />
<xs:element name="year" type="xs:string" minOccurs="0" />
<xs:element name="bodystyle" type="xs:string" minOccurs="0" />
<xs:element name="vehicletype" type="xs:string" minOccurs="0" />
<xs:element name="chassisnumber" type="xs:string" minOccurs="0" />
<xs:element name="enginenumber" type="xs:string" minOccurs="0" />
<xs:element name="cc" type="xs:string" minOccurs="0" />
<xs:element name="countryoforigin" type="xs:string" minOccurs="0" />
<xs:element name="fueltype" type="xs:string" minOccurs="0" />
<xs:element name="transmission" type="xs:string" minOccurs="0" />
<xs:element name="speeds" type="xs:string" minOccurs="0" />
<xs:element name="modelcode" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1">
<NewDataSet xmlns="">
<SearchResults diffgr:id="SearchResults1" msdata:rowOrder="0">
<VehicleID>13971</VehicleID>
<make>SUBARU</make>
<model>LEGACY</model>
<series>BE</series>
<engine>1994cc, EJ204 F4 16v DOHC MPFI {114KW}</engine>
<yearrange>12/98~04/03</yearrange>
<details> B4 RS, 4D Sedan, AWD, AT/MT</details>
<chassis>BE5</chassis>
<Countryoforigin>JAPAN</Countryoforigin>
<VIN>BE5</VIN>
</SearchResults>
<SearchResults diffgr:id="SearchResults2" msdata:rowOrder="1">
<VehicleID>14379</VehicleID>
<make>SUBARU</make>
<model>LEGACY</model>
<series>BE</series>
<engine>1994cc, EJ208 F4 16v DOHC Twin Turbo MPFI {206KW}</engine>
<yearrange>12/98~04/03</yearrange>
<details> B4 RSK, 4D Sedan, AWD, MT</details>
<chassis>BE5</chassis>
<Countryoforigin>JAPAN</Countryoforigin>
<VIN>BE5</VIN>
</SearchResults>
<ChargeDetails diffgr:id="ChargeDetails1" msdata:rowOrder="0">
<ChargeApplies>1</ChargeApplies>
</ChargeDetails>
</NewDataSet>
</diffgr:diffgram>
</DataSet>
```
我可以验证XML是否正确,因为我尝试了在线转换器并且结果可用。而我得到的是空数组或空对象。
有人可以帮忙吗?
答案 0 :(得分:1)
因此,我发现XML to JSON函数确实可以很好地工作,但由于我将名称空间合并到了键名中,因此我无法满足其需要,并且我需要从键中删除名称空间。
问题是,当您在XML元素中合并命名空间时,将转换为Array或JSON的方式将删除命名空间的子节点。我意识到,如果在将字符串转换为XML元素之前先从XML字符串中删除名称空间,那么json_encode函数将按预期工作,并且不会删除任何数据。
因此,对于其他遇到此问题的人,这是我根据自己的需要解决问题的方法。
我知道发送给我的XML没有命名冲突。使用命名空间的唯一原因是标识XML数据那部分的源。 我知道所有正在使用的命名空间 这是我所做的
function removeNamespaceFromXML( $xml )
{
// Because I know all of the the namespaces that will possibly appear in
// in the XML string I can just hard code them and check for
// them to remove them
$toRemove = ['rap', 'turss', 'crim', 'cred', 'j', 'rap-code', 'evic'];
// This is part of a regex I will use to remove the namespace declaration from string
$nameSpaceDefRegEx = '(\S+)=["\']?((?:.(?!["\']?\s+(?:\S+)=|[>"\']))+.)["\']?';
// Cycle through each namespace and remove it from the XML string
foreach( $toRemove as $remove ) {
// First remove the namespace from the opening of the tag
$xml = str_replace('<' . $remove . ':', '<', $xml);
// Now remove the namespace from the closing of the tag
$xml = str_replace('</' . $remove . ':', '</', $xml);
// This XML uses the name space with CommentText, so remove that too
$xml = str_replace($remove . ':commentText', 'commentText', $xml);
// Complete the pattern for RegEx to remove this namespace declaration
$pattern = "/xmlns:{$remove}{$nameSpaceDefRegEx}/";
// Remove the actual namespace declaration using the Pattern
$xml = preg_replace($pattern, '', $xml, 1);
}
// Return sanitized and cleaned up XML with no namespaces
return $xml;
}
function namespacedXMLToArray($xml)
{
// One function to both clean the XML string and return an array
return json_decode(json_encode(simplexml_load_string(removeNamespaceFromXML($xml))), true);
}
通过调用namespacedXMLToArray()函数,我可以简单地得到一个100%好的数组。
希望这种方法对其他人有帮助。我敢肯定,如果您不知道可能存在的名称空间,则可以使用RegEx查找各种已定义的名称空间,然后在知道名称后将其删除。