php 解析 xml 文档
php parse xml document
过去 2 小时我一直在尝试解析此 xml 文档以循环 'table' 元素,但它不起作用!我试过这个主要作为参考,但它不起作用 simplexml_load_string returns blank array
这是我的 XML,我如何遍历 'table' 节点?
<?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>
您可能对 NameSpaceURI 有一些疑问。
NamespaceURI 的特征是带有冒号的标记 (<soap:Envelope>
) 和 NamespaceURI 声明,属性(通常是根元素)带有“xmlns:”前缀:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" .... >
<!-- └──┬─┘└┬─┘ └────────────────────────┬──────────────┘
│ └──────┐ │
NameSpace Declaration NameSpace Prefix NameSpaceURI -->
应用于没有前缀的标签的主要 NameSpaceURI 以属性“xmlns”为特征,没有逗号。
要搜索 NameSpaceURI 元素,您可以使用 ->children()
,使用相对 NameSpaceURI 作为参数:
$children = $xml->children( 'http://schemas.xmlsoap.org/soap/envelope/' );
或者,添加可选参数is_prefix_,NameSpaceURI前缀:
$children = $xml->children( 'soap', True );
在您的情况下,在访问 <Table>
之前,您必须 select 直接父节点:
$xml = simplexml_load_file( $filePath );
$body = $xml->children( 'soap', True );
$GetMovieListResult = $body->children();
$NewDataSet = $GetMovieListResult->children()->DatasetXML->NewDataSet;
# └───────────────────┬┘
# Here we can use standard syntax ─┘
至此,我们可以抓取所有电影名称:
$movieNames = array[];
foreach( $NewDataSet->Table as $table )
{
$movieNames[] = (string) $table->Movie_strName;
}
现在 $movieNames
你有数组:
Array
(
[0] => BATMAN Vs SUPERMAN
[1] => BATMAN Vs SUPERMAN VIP
)
通过此方法,您可以检索任何其他节点值。
使用 XPath
一种更舒适的方法是使用 XPath,这是一种使用路径表达式在 XML 文档中导航的语法。要在命名空间 XML 中使用 XPath,首先我们必须注册要在模式中使用的命名空间:
$xml->registerXPathNamespace( 'xmlns', 'http://vista.co.nz/services/WSVistaWebClient.DataTypes/1/' );
在这种情况下,我注册了主NameSpaceURI1。然后我们可以搜索模式:
$tables = '//xmlns:Table';
模式开头的双斜杠表示:“搜索匹配以下模式的节点,无论它们在哪里”2。现在,我们有一组节点可以作为先例进行迭代:
foreach( $tables as $table )
{
(...)
- 阅读更多关于 XPath
备注:
我们可以使用任何字符组合注册NameSpaces,不一定是文档中使用的那种。 IE。如果我以这种方式注册主 NS:$xml->registerXPathNamespace( 'x', 'http://vista.co.nz/services/WSVistaWebClient.DataTypes/1/' );
,那么我可以这样构造 XPath 模式://x:Table
.
要搜索精确的降序树,我们可以使用/
代替//
。然而,在这种情况下,我们必须注册树中出现的所有名称空间。
过去 2 小时我一直在尝试解析此 xml 文档以循环 'table' 元素,但它不起作用!我试过这个主要作为参考,但它不起作用 simplexml_load_string returns blank array
这是我的 XML,我如何遍历 'table' 节点?
<?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>
您可能对 NameSpaceURI 有一些疑问。
NamespaceURI 的特征是带有冒号的标记 (<soap:Envelope>
) 和 NamespaceURI 声明,属性(通常是根元素)带有“xmlns:”前缀:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" .... >
<!-- └──┬─┘└┬─┘ └────────────────────────┬──────────────┘
│ └──────┐ │
NameSpace Declaration NameSpace Prefix NameSpaceURI -->
应用于没有前缀的标签的主要 NameSpaceURI 以属性“xmlns”为特征,没有逗号。
要搜索 NameSpaceURI 元素,您可以使用 ->children()
,使用相对 NameSpaceURI 作为参数:
$children = $xml->children( 'http://schemas.xmlsoap.org/soap/envelope/' );
或者,添加可选参数is_prefix_,NameSpaceURI前缀:
$children = $xml->children( 'soap', True );
在您的情况下,在访问 <Table>
之前,您必须 select 直接父节点:
$xml = simplexml_load_file( $filePath );
$body = $xml->children( 'soap', True );
$GetMovieListResult = $body->children();
$NewDataSet = $GetMovieListResult->children()->DatasetXML->NewDataSet;
# └───────────────────┬┘
# Here we can use standard syntax ─┘
至此,我们可以抓取所有电影名称:
$movieNames = array[];
foreach( $NewDataSet->Table as $table )
{
$movieNames[] = (string) $table->Movie_strName;
}
现在 $movieNames
你有数组:
Array
(
[0] => BATMAN Vs SUPERMAN
[1] => BATMAN Vs SUPERMAN VIP
)
通过此方法,您可以检索任何其他节点值。
使用 XPath
一种更舒适的方法是使用 XPath,这是一种使用路径表达式在 XML 文档中导航的语法。要在命名空间 XML 中使用 XPath,首先我们必须注册要在模式中使用的命名空间:
$xml->registerXPathNamespace( 'xmlns', 'http://vista.co.nz/services/WSVistaWebClient.DataTypes/1/' );
在这种情况下,我注册了主NameSpaceURI1。然后我们可以搜索模式:
$tables = '//xmlns:Table';
模式开头的双斜杠表示:“搜索匹配以下模式的节点,无论它们在哪里”2。现在,我们有一组节点可以作为先例进行迭代:
foreach( $tables as $table )
{
(...)
- 阅读更多关于 XPath
备注:
我们可以使用任何字符组合注册NameSpaces,不一定是文档中使用的那种。 IE。如果我以这种方式注册主 NS:
$xml->registerXPathNamespace( 'x', 'http://vista.co.nz/services/WSVistaWebClient.DataTypes/1/' );
,那么我可以这样构造 XPath 模式://x:Table
.要搜索精确的降序树,我们可以使用
/
代替//
。然而,在这种情况下,我们必须注册树中出现的所有名称空间。