我有以下xml数据集,它们来自我必须使用的API:
<?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>
这个问题是,如果我执行以下操作:
<?php $result = simplexml_load_string( $xml, 'SimpleXMLElement', 0, 'xs' );
echo ($result ? 'Valid XML' : 'Parse Error'), PHP_EOL;
print_r( $result );
结果是:
Parse Error
SimpleXMLElement Object
(
)
作为后备解决方案,我使用了:
$p = xml_parser_create();
xml_parse_into_struct( $p, $xml, $result, $index );
xml_parser_free( $p );
哪个工作正常。
另一个问题是,从相同的API我也有这样的响应:
<?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>
与simplexml_load_string()
函数完美配合。这意味着我将XML解析器用于某些响应,将simplexml_load_string()
用于其他响应,这不太容易维护。
这里的问题是:有什么方法可以使用simplexml_load_string()
解析两种响应类型?还是应该只切换到XML Parser或DOMDocument或其他类似的库?
注意::从第一个XML代码段开始,我只想从NewDataSet
节点提取内容。
让我知道是否需要更多详细信息。任何帮助表示赞赏。
答案 0 :(得分:1)
请小心检查解析错误。空的SimpleXMLElement可以解析为false
,并且如果您的XML不包含文本或仅包含命名空间元素,则您的错误检查可能是错误的。检查解析错误时,请始终使用=== false
。
改为使用此:
echo ($result !== false ? 'Valid XML' : 'Parse Error'), PHP_EOL;
答案 1 :(得分:0)
解决方案是不使用simplexml_load_string()
,而是通过创建新的SimpleXMLElement进行解析。它仍然没有使用simplexml_load_string()
,但允许我使用SimpleXMLElement
来处理它。
我的测试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>
我的PHP代码
$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>";
结果
SimpleXMLElement Object
(
[ID_Building] => 333
[Name] => Example Building Name
[Description] => SimpleXMLElement Object
(
)
)
感谢您的帮助!