Reputation: 389
I've been trying to parse this xml document to loop the 'table' element for the last 2 hours, but it's not working ! I've tried this mainly as reference but it's not working simplexml_load_string returns blank array
here's my XML, how can I loop through the 'table' node ?
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><GetMovieListResult xmlns="http://vista.co.nz/services/WSVistaWebClient.DataTypes/1/"><Result>OK</Result><DatasetXML><NewDataSet>
<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="Table">
<xs:complexType>
<xs:sequence>
<xs:element name="Cinema_strID" type="xs:string" minOccurs="0" />
<xs:element name="Movie_strID" type="xs:string" minOccurs="0" />
<xs:element name="Movie_strName" type="xs:string" minOccurs="0" />
<xs:element name="Movie_strRating" type="xs:string" minOccurs="0" />
<xs:element name="Movie_strName_2" type="xs:string" minOccurs="0" />
<xs:element name="Movie_strRating_2" type="xs:string" minOccurs="0" />
<xs:element name="Movie_HOFilmCode" type="xs:string" minOccurs="0" />
<xs:element name="Movie_intFCode" type="xs:int" minOccurs="0" />
<xs:element name="CinOperator_strCode" type="xs:int" minOccurs="0" />
<xs:element name="CinOperator_strName" type="xs:int" minOccurs="0" />
<xs:element name="Event_strCode" type="xs:string" minOccurs="0" />
<xs:element name="Event_strFilmsIndependent" type="xs:string" minOccurs="0" />
<xs:element name="MemberMovie" type="xs:string" minOccurs="0" />
<xs:element name="HOPK" type="xs:string" minOccurs="0" />
<xs:element name="Movie_intList_Pos" type="xs:int" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<Table>
<Cinema_strID>0</Cinema_strID>
<Movie_strID>0010000845</Movie_strID>
<Movie_strName>BATMAN Vs SUPERMAN</Movie_strName>
<Movie_strRating>PG13</Movie_strRating>
<Movie_strName_2 />
<Movie_strRating_2 />
<Movie_HOFilmCode />
<Movie_intFCode>0</Movie_intFCode>
<Event_strCode />
<MemberMovie>N</MemberMovie>
<HOPK />
<Movie_intList_Pos>50</Movie_intList_Pos>
</Table>
<Table>
<Cinema_strID>0</Cinema_strID>
<Movie_strID>0010000846</Movie_strID>
<Movie_strName>BATMAN Vs SUPERMAN VIP</Movie_strName>
<Movie_strRating>PG13</Movie_strRating>
<Movie_strName_2 />
<Movie_strRating_2 />
<Movie_HOFilmCode />
<Movie_intFCode>0</Movie_intFCode>
<Event_strCode />
<MemberMovie>N</MemberMovie>
<HOPK />
<Movie_intList_Pos>50</Movie_intList_Pos>
</Table>
</NewDataSet></DatasetXML></GetMovieListResult></soap:Body></soap:Envelope>
Upvotes: 1
Views: 96
Reputation: 11689
Probably you have some issue with NameSpaceURIs.
NamespaceURIs are characterized by tags with colon (<soap:Envelope>
) and by NamespaceURI declaration, an attribute (usually of root element) with “xmlns:” prefix:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" .... >
<!-- └──┬─┘└┬─┘ └────────────────────────┬──────────────┘
│ └──────┐ │
NameSpace Declaration NameSpace Prefix NameSpaceURI -->
The main NameSpaceURI, applied to tags without prefix, is characterized by attribute “xmlns”, without comma.
To search for NameSpaceURI elements, you can use ->children()
, using as argument relative NameSpaceURI:
$children = $xml->children( 'http://schemas.xmlsoap.org/soap/envelope/' );
or, adding optional parameter is_prefix_, the NameSpaceURI prefix:
$children = $xml->children( 'soap', True );
In your case, before accessing <Table>
, you have to select direct parent node:
$xml = simplexml_load_file( $filePath );
$body = $xml->children( 'soap', True );
$GetMovieListResult = $body->children();
$NewDataSet = $GetMovieListResult->children()->DatasetXML->NewDataSet;
# └───────────────────┬┘
# Here we can use standard syntax ─┘
At this point, we can catch, e.g., all movie names:
$movieNames = array[];
foreach( $NewDataSet->Table as $table )
{
$movieNames[] = (string) $table->Movie_strName;
}
Now $movieNames
array you have:
Array
(
[0] => BATMAN Vs SUPERMAN
[1] => BATMAN Vs SUPERMAN VIP
)
By this method, you can retrieve any other node value.
A more comfortable method is to use XPath, a syntax that uses path expressions to navigate in XML documents. To using XPath in a Namespaced XML, first we have to register the Namespace(s) that we want to use in the pattern:
$xml->registerXPathNamespace( 'xmlns', 'http://vista.co.nz/services/WSVistaWebClient.DataTypes/1/' );
In this case, I have registered main NameSpaceURI1. Then we can search for the pattern:
$tables = '//xmlns:Table';
The double slash at beginning of pattern means: “Search for nodes matching following pattern no matter where they are”2. Now, we have a set of nodes that we can iterate through as precedent example:
foreach( $tables as $table )
{
(...)
Notes:
We can use any characters combination registering NameSpaces, not necessarily that one used in the document. I.e. if I register main NS in this way: $xml->registerXPathNamespace( 'x', 'http://vista.co.nz/services/WSVistaWebClient.DataTypes/1/' );
, then I can construct XPath pattern in this way: //x:Table
.
To search the exact descending tree, we can use /
instead of //
. In this case, however, we have to register all NameSpaces that appear in the tree.
Upvotes: 1