Проблема с элементом DOM GetElementByTagName в переполнении стека

<FlightSegment DepartureDateTime="2016-09-20T06:05:00" ArrivalDateTime="2016-09-20T08:05:00" FlightNumber="716" ResBookDesigCode="N">
<FlightDuration>2016-09-14T02:00:00</FlightDuration>
<DepartureAirport LocationCode="IST" Terminal="I" />
<ArrivalAirport LocationCode="KBP" />
<OperatingAirline Code="PS" />
<Equipment AirEquipType="73H" />
<MarketingAirline Code="PS" />
<BookingClassAvails>
<BookingClassAvail ResBookDesigCode="N" ResBookDesigQuantity="9" RPH="ADT" AvailablePTC="ADT" ResBookDesigCabinCode="M" FareBasis="NL1LTP4" />
</BookingClassAvails>
</FlightSegment>
<FlightSegment DepartureDateTime="2016-09-20T09:50:00" ArrivalDateTime="2016-09-20T11:55:00" FlightNumber="101" ResBookDesigCode="N">
<FlightDuration>2016-09-14T03:05:00</FlightDuration>
<DepartureAirport LocationCode="KBP" />
<ArrivalAirport LocationCode="AMS" />
<OperatingAirline Code="PS" />
<Equipment AirEquipType="73R" />
<MarketingAirline Code="PS" />
<BookingClassAvails>
<BookingClassAvail ResBookDesigCode="N" ResBookDesigQuantity="9" RPH="ADT" AvailablePTC="ADT" ResBookDesigCabinCode="M" FareBasis="NL1LTP4" />
</BookingClassAvails>
</FlightSegment>

Есть два сегмента полета.
У нас нет идентификаторов в этом коде, поэтому

  1. Как я мог бы разделить этот код на блоки, чтобы использовать атрибуты из первых <FlightSegment> блок?
  2. Также мне нужно посчитать <FlightSegments>,

Пожалуйста помоги! )

0

Решение

Вы можете использовать эту функцию для преобразования узла XML в (вложенный) массив:

function domToArray($node) {
$arr = [];
// Add all attributes of this node as key/values:
foreach ($node->attributes as $attribute) {
$arr[$attribute->nodeName] = $attribute->nodeValue;
}
// Iterate through the child nodes
foreach ($node->childNodes as $child) {
if ($child->nodeType === XML_TEXT_NODE) {
// Assign the text content to a "value" key
if (trim($child->textContent)!== '') {
$arr['value'] = $child->textContent;
}
} else if ($child->nodeType === XML_ELEMENT_NODE) {
// Create key/value pairs for child nodes, using recursion.
// If the children are repeated elements, then build
// an indexed array, otherwise an associative array.
if (preg_replace("/y$/", "ie", $child->nodeName) ."s" === $node->nodeName) {
$arr[] = domToArray($child);
} else {
$arr[$child->nodeName] = domToArray($child);
}
}
}
return $arr;
}

Сначала вы должны создать DOMDocument и прочитайте строку XML в нее. Обратите внимание, что предоставленный вами фрагмент XML должен быть заключен в один элемент, который я назвал FlightSegments специально — кратное FlightSegment из которых у вас есть 2:

$doc = new DOMDocument();
$doc->loadXML("<FlightSegments>$xml</FlightSegments>");

После этого вы можете вызвать функцию, о которой я упоминал выше:

// Convert XML to nested array:
$flightSegments = domToArray($doc->documentElement);

Вот некоторые результаты, которые вы можете получить из этого массива:

// Number of FlightSegments:
echo "Number of FlightSegment elements: " . count($flightSegments) . "<br>";

echo "DepartureDateTime of first FlightSegment: " . $flightSegments[0]['DepartureDateTime'] . "<br>";

echo "All information:<br>";

print_r ($flightSegments);

Смотрите, это работает на eval.in.

С предоставленным вами примером XML вы получите следующий код:

Number of FlightSegment elements: 2
DepartureDateTime of first FlightSegment: 2016-09-20T06:05:00
All information:
Array
(
[0] => Array
(
[DepartureDateTime] => 2016-09-20T06:05:00
[ArrivalDateTime] => 2016-09-20T08:05:00
[FlightNumber] => 716
[ResBookDesigCode] => N
[FlightDuration] => Array
(
[value] => 2016-09-14T02:00:00
)

[DepartureAirport] => Array
(
[LocationCode] => IST
[Terminal] => I
)

[ArrivalAirport] => Array
(
[LocationCode] => KBP
)

[OperatingAirline] => Array
(
[Code] => PS
)

[Equipment] => Array
(
[AirEquipType] => 73H
)

[MarketingAirline] => Array
(
[Code] => PS
)

[BookingClassAvails] => Array
(
[0] => Array
(
[ResBookDesigCode] => N
[ResBookDesigQuantity] => 9
[RPH] => ADT
[AvailablePTC] => ADT
[ResBookDesigCabinCode] => M
[FareBasis] => NL1LTP4
)

)

)

[1] => Array
(
[DepartureDateTime] => 2016-09-20T09:50:00
[ArrivalDateTime] => 2016-09-20T11:55:00
[FlightNumber] => 101
[ResBookDesigCode] => N
[FlightDuration] => Array
(
[value] => 2016-09-14T03:05:00
)

[DepartureAirport] => Array
(
[LocationCode] => KBP
)

[ArrivalAirport] => Array
(
[LocationCode] => AMS
)

[OperatingAirline] => Array
(
[Code] => PS
)

[Equipment] => Array
(
[AirEquipType] => 73R
)

[MarketingAirline] => Array
(
[Code] => PS
)

[BookingClassAvails] => Array
(
[0] => Array
(
[ResBookDesigCode] => N
[ResBookDesigQuantity] => 9
[RPH] => ADT
[AvailablePTC] => ADT
[ResBookDesigCabinCode] => M
[FareBasis] => NL1LTP4
)

)

)

)

Изменить после того, как вы предоставили полный XML

Я не уверен, в чем ваша проблема, потому что в комментариях вы поделились кодом, где вы успешно просматриваете свой XML.

Просто отметим, что вы можете использовать вышеупомянутую функцию, чтобы превратить полный XML в массив (я внес одно исправление в функцию, чтобы правильно идентифицировать множественное число имени тега, заканчивающегося на «у»).

Вот как бы вы назвали это в своем XML:

$soap = domToArray($xmlDoc->documentElement);

Содержание $soap будет (я усек это):

Array
(
[soap:Body] => Array
(
[SearchFlightResponse] => Array
(
[OTA_AirLowFareSearchRS] => Array
(
[Version] => 0
[HasMoreResult] => Array
(
[value] => false
)

[Success] => Array
(
)

[PricedItineraries] => Array
(
[0] => Array
(
[Currency] => USD
[ProviderType] => AmadeusProvider
[SequenceNumber] => 0
[AirItinerary] => Array
(
[OriginDestinationOptions] => Array
(
[0] => Array
(
[RefNumber] => 0
[DirectionId] => 0
[ElapsedTime] => 0650
[FlightSegment] => Array
(
[DepartureDateTime] => 2016-09-20T09:50:00
[ArrivalDateTime] => 2016-09-20T11:55:00
[FlightNumber] => 101
[ResBookDesigCode] => N
[FlightDuration] => Array
(
[value] => 2016-09-14T03:05:00
)

[DepartureAirport] => Array
(
[LocationCode] => KBP
)

[ArrivalAirport] => Array
(
[LocationCode] => AMS
)

[OperatingAirline] => Array
(
[Code] => PS
)

[Equipment] => Array
(
[AirEquipType] => 73R
)

[MarketingAirline] => Array
(
[Code] => PS
)

[BookingClassAvails] => Array
(
[0] => Array
(
[ResBookDesigCode] => N
[ResBookDesigQuantity] => 9
[RPH] => ADT
[AvailablePTC] => ADT
[ResBookDesigCabinCode] => M
[FareBasis] => NL1LTP4
)

)

Теперь вы можете написать код:

$itineries = $soap['soap:Body']['SearchFlightResponse']['OTA_AirLowFareSearchRS']['PricedItineraries'];
foreach ($itineries as $itinery) {
// ... etc. Always array access.
}
1

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

Теперь ваша функция создает массив из последнего сегмента XML-документа:

<?php

function domToArray($node) {
$arr = [];
// Add all attributes of this node as key/values:
foreach ($node->attributes as $attribute) {
$arr[$attribute->nodeName] = $attribute->nodeValue;
}
$useName = true;
// Iterate through the child nodes
foreach ($node->childNodes as $child) {
if ($child->nodeType === XML_TEXT_NODE) {
// Assign the text content to a "value" key
if (trim($child->textContent)!== '') {
$arr['value'] = $child->textContent;
}
} else if ($child->nodeType === XML_ELEMENT_NODE) {
// Create key/value pairs for child nodes, using recursion.
// If the children are repeated elements, then build
// an indexed array, otherwise an associative array.
if ($child->nodeName ."s" === $node->nodeName) {
$arr[] = domToArray($child);
} else {
$arr[$child->nodeName] = domToArray($child);
}
}
}
return $arr;
}
$xmlDoc = new DOMDocument();
$xmlDoc->load("response.xml");
$soap = domToArray($xmlDoc->documentElement);
print_r($soap);

?>

Здесь вы можете увидеть весь документ целиком: response.xml

И вот что содержит $soap: массив

Ваше решение было идеальным:

// If the children are repeated elements, then build
// an indexed array, otherwise an associative array.

…но он не создает индексированный массив, когда я пытаюсь загрузить response.xml. Это просто построить массивно с последним FlightSegment …

Постскриптум Я не тот человек, мы просто работаем вместе. )

0

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