Reputation: 3005
I have the following xml DataSet which comes from an API I have to use:
<?xml version="1.0" encoding="utf-8"?>
<DataSet xmlns="http://examplesite.com/WebRes">
<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="BuildingInfo">
<xs:complexType>
<xs:sequence>
<xs:element name="ID_Building" type="xs:int" minOccurs="0" />
<xs:element name="Name" type="xs:string" minOccurs="0" />
<xs:element name="Description" 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="">
<BuildingInfo diffgr:id="BuildingInfo1" msdata:rowOrder="0">
<ID_Building>333</ID_Building>
<Name>Example Building Name</Name>
<Description />
</BuildingInfo>
</NewDataSet>
<NewDataSet xmlns="">
<BuildingInfo diffgr:id="BuildingInfo1" msdata:rowOrder="0">
<ID_Building>334</ID_Building>
<Name>Example Building Name2</Name>
<Description />
</BuildingInfo>
</NewDataSet>
</diffgr:diffgram>
</DataSet>
The problem with this one is that if I do the following:
<?php $result = simplexml_load_string( $xml, 'SimpleXMLElement', 0, 'xs' );
echo ($result ? 'Valid XML' : 'Parse Error'), PHP_EOL;
print_r( $result );
The result is:
Parse Error
SimpleXMLElement Object
(
)
As a fallback solution I used:
$p = xml_parser_create();
xml_parse_into_struct( $p, $xml, $result, $index );
xml_parser_free( $p );
Which is working just fine.
The other problem is that from the same API I also have responses like this:
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfRoomTypeBuildingsDetails xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://examplesite.com/WebRes">
<RoomTypeBuildingsDetails>
<ID_RoomType>123</ID_RoomType>
<RoomTypeName>Post Name</RoomTypeName>
<RoomTypeDescription>This is the description</RoomTypeDescription>
<GuestMax>2</GuestMax>
</RoomTypeBuildingsDetails>
</ArrayOfRoomTypeBuildingsDetails>
Which work perfectly with the simplexml_load_string()
function. That means I am using XML Parser for some of the responses and the simplexml_load_string()
for the others which is not very easy to maintain.
The question here is: is there any way to parse both of the response types using simplexml_load_string()
? or should I just switch to the XML Parser or DOMDocument or other similar library?
NOTE: from the first XML snippet, I am only interested in pulling the contents from the NewDataSet
node.
Let me know if you need any more details. Any help is appreciated.
Upvotes: 0
Views: 323
Reputation: 3005
The solution was to not use simplexml_load_string()
but to parse it by creating a new SimpleXMLElement. It is still not using simplexml_load_string()
but it allows me to use SimpleXMLElement
to handle it.
My Test XML
<?xml version="1.0" encoding="utf-8"?>
<DataSet xmlns="http://examplesite.com/WebRes">
<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="BuildingInfo">
<xs:complexType>
<xs:sequence>
<xs:element name="ID_Building" type="xs:int" minOccurs="0" />
<xs:element name="Name" type="xs:string" minOccurs="0" />
<xs:element name="Description" 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="">
<BuildingInfo diffgr:id="BuildingInfo1" msdata:rowOrder="0">
<ID_Building>333</ID_Building>
<Name>Example Building Name</Name>
<Description />
</BuildingInfo>
</NewDataSet>
<NewDataSet xmlns="">
<BuildingInfo diffgr:id="BuildingInfo1" msdata:rowOrder="0">
<ID_Building>334</ID_Building>
<Name>Example Building Name2</Name>
<Description />
</BuildingInfo>
</NewDataSet>
</diffgr:diffgram>
</DataSet>
My PHP Code
$sxe = new SimpleXMLElement($quote_response);
$sxe->registerXPathNamespace('d', 'urn:schemas-microsoft-com:xml-diffgram-v1');
$result = $sxe->xpath("//NewDataSet");
echo "<pre>";
foreach ($result[0] as $title) {
print_r($title);
}
echo "</pre>";
The Result
SimpleXMLElement Object
(
[ID_Building] => 333
[Name] => Example Building Name
[Description] => SimpleXMLElement Object
(
)
)
Thanks for the help!
Upvotes: 0
Reputation: 4952
Be careful checking for parse errors. An empty SimpleXMLElement may resolve to false
, and if your XML contains no text or only contains namespaced elements your error check may be wrong. Always use === false
when checking for parse errors.
Use this instead:
echo ($result !== false ? 'Valid XML' : 'Parse Error'), PHP_EOL;
Upvotes: 1