php parse xml document

Я пытался проанализировать этот XML-документ, чтобы зациклить элемент ‘table’ за последние 2 часа, но он не работает! Я пробовал это в основном в качестве ссылки, но это не работает simplexml_load_string возвращает пустой массив

вот мой XML, как я могу пройти через узел «таблица»?

    <?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>

1

Решение

Возможно, у вас есть проблемы с NameSpaceURI.

NamespaceURIs характеризуются тегами с двоеточием (<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>, вы должны выбрать прямой родительский узел:

$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. Чтобы использовать XPath в XML с пространством имен, сначала мы должны зарегистрировать пространство (имена), которое мы хотим использовать в шаблоне:

$xml->registerXPathNamespace( 'xmlns', 'http://vista.co.nz/services/WSVistaWebClient.DataTypes/1/' );

В этом случае я зарегистрировал основное NameSpaceURI1. Тогда мы можем искать шаблон:

$tables = '//xmlns:Table';

Двойная косая черта в начале шаблона означает: «Поиск узлов, соответствующих следующему шаблону, независимо от того, где они находятся»2. Теперь у нас есть набор узлов, которые мы можем перебрать в качестве предыдущего примера:

foreach( $tables as $table )
{
(...)

  • Узнайте больше о XPath

Заметки:

  1. Мы можем использовать любую комбинацию символов, регистрирующую пространства имен, не обязательно ту, которая используется в документе. То есть если я зарегистрирую основной NS следующим образом: $xml->registerXPathNamespace( 'x', 'http://vista.co.nz/services/WSVistaWebClient.DataTypes/1/' );тогда я могу построить шаблон XPath следующим образом: //x:Table,

  2. Чтобы найти точное нисходящее дерево, мы можем использовать / вместо //, В этом случае, однако, мы должны зарегистрировать все пространства имен, которые появляются в дереве.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]