DOM 元素 GetElementsByTagName 在 PHP 中出现问题
Issue with DOM element GetElementByTagName in PHP
<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>
有两个航段。
我们在此代码中没有任何标识符,因此,
- 如何将此代码按块划分以使用第一个
<FlightSegment>
块中的属性?
- 我还需要数
<FlightSegments>
。
请帮助! )
您可以使用此函数将 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 转换为数组(我对该函数进行了一次更正以正确识别以 [=47 结尾的标签名称的复数形式=]).
以下是您在 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.
}
现在您的函数从 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
的内容:Array
您的决定很理想:
// If the children are repeated elements, then build
// an indexed array, otherwise an associative array.
...但是当我尝试加载 response.xml 时,它不会构建索引数组。它只是用最后一个 FlightSegment 建立起来......
P.S。我不是同一个人,我们只是一起工作。 )
<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>
有两个航段。 我们在此代码中没有任何标识符,因此,
- 如何将此代码按块划分以使用第一个
<FlightSegment>
块中的属性? - 我还需要数
<FlightSegments>
。
请帮助! )
您可以使用此函数将 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 转换为数组(我对该函数进行了一次更正以正确识别以 [=47 结尾的标签名称的复数形式=]).
以下是您在 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.
}
现在您的函数从 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
的内容:Array
您的决定很理想:
// If the children are repeated elements, then build
// an indexed array, otherwise an associative array.
...但是当我尝试加载 response.xml 时,它不会构建索引数组。它只是用最后一个 FlightSegment 建立起来......
P.S。我不是同一个人,我们只是一起工作。 )