Используя стандартные DOMDocument
и DOMXpath
, довольно просто извлечь (клонировать) части документа, которые можно использовать позже, по вашему желанию.
$xml='<?xml version="1.0" encoding="UTF-8"?>
<air:LowFareSearchRsp xmlns:air="http://www.travelport.com/schema/air_v48_0" TraceId="trace" TransactionId="5C13B61C0A076478D128A37655BD80F6" ResponseTime="3150" DistanceUnits="MI" CurrencyType="BDT">
<air:AirPricingSolution Key="lR26Z14R2BKAVzCGAAAAAA==" TotalPrice="BDT53498" BasePrice="USD444.00" ApproximateTotalPrice="BDT53498" ApproximateBasePrice="BDT37186" EquivalentBasePrice="BDT37186" Taxes="BDT16312" ApproximateTaxes="BDT16312">
<air:Journey TravelTime="P0DT4H10M0S">
<air:AirSegmentRef Key="lR26Z14R2BKAWzCGAAAAAA=="/>
</air:Journey>
<air:Journey TravelTime="P0DT4H0M0S">
<air:AirSegmentRef Key="lR26Z14R2BKAYzCGAAAAAA=="/>
</air:Journey>
<air:LegRef Key="lR26Z14R2BKAazCGAAAAAA=="/>
<air:LegRef Key="lR26Z14R2BKAbzCGAAAAAA=="/>
<air:AirPricingInfo Key="lR26Z14R2BKAczCGAAAAAA==" TotalPrice="BDT26749" BasePrice="USD222.00" ApproximateTotalPrice="BDT26749" ApproximateBasePrice="BDT18593" EquivalentBasePrice="BDT18593" Taxes="BDT8156" ApproximateTaxes="BDT8156" LatestTicketingTime="2020-01-06" PricingMethod="Guaranteed" ETicketability="Yes" PlatingCarrier="MH" ProviderCode="1G" Cat35Indicator="false">
<air:FareInfoRef Key="lR26Z14R2BKAlzCGAAAAAA=="/>
<air:FareInfoRef Key="lR26Z14R2BKA0zCGAAAAAA=="/>
<air:BookingInfo BookingCode="N" BookingCount="9" CabinClass="Economy" FareInfoRef="lR26Z14R2BKAlzCGAAAAAA==" SegmentRef="lR26Z14R2BKAWzCGAAAAAA=="/>
<air:BookingInfo BookingCode="N" BookingCount="9" CabinClass="Economy" FareInfoRef="lR26Z14R2BKA0zCGAAAAAA==" SegmentRef="lR26Z14R2BKAYzCGAAAAAA=="/>
<air:TaxInfo Category="BD" Amount="BDT500" Key="lR26Z14R2BKAdzCGAAAAAAAA"/>
<air:TaxInfo Category="E5" Amount="BDT75" Key="lR26Z14R2BKAezCGAAAAAAAA"/>
<air:TaxInfo Category="OW" Amount="BDT2000" Key="lR26Z14R2BKAfzCGAAAAAAAA"/>
<air:TaxInfo Category="UT" Amount="BDT3000" Key="lR26Z14R2BKAgzCGAAAAAAAA"/>
<air:TaxInfo Category="G1" Amount="BDT407" Key="lR26Z14R2BKAhzCGAAAAAAAA"/>
<air:TaxInfo Category="H8" Amount="BDT21" Key="lR26Z14R2BKAizCGAAAAAAAA"/>
<air:TaxInfo Category="MY" Amount="BDT1483" Key="lR26Z14R2BKAjzCGAAAAAAAA"/>
<air:TaxInfo Category="YQ" Amount="BDT670" Key="lR26Z14R2BKAkzCGAAAAAAAA"/>
<air:FareCalc>DAC MH KUL 111.00NBC6MSBD MH DAC 111.00NBC6MSBD NUC222.00END ROE1.0</air:FareCalc>
<air:PassengerType Code="ADT"/>
<air:PassengerType Code="ADT"/>
<air:ChangePenalty PenaltyApplies="Anytime">
<air:Amount>BDT3350.0</air:Amount>
</air:ChangePenalty>
<air:CancelPenalty NoShow="true" PenaltyApplies="Anytime">
<air:Percentage>100.00</air:Percentage>
</air:CancelPenalty>
</air:AirPricingInfo>
</air:AirPricingSolution>
<air:AirPricingSolution>
<fruit>cherry</fruit>
</air:AirPricingSolution>
<air:AirPricingSolution>
<fruit>banana</fruit>
</air:AirPricingSolution>
<air:AirPricingSolution>
<fruit>apple</fruit>
</air:AirPricingSolution>
</air:LowFareSearchRsp>';
/* keep errors from interfering with operatons */
libxml_use_internal_errors( true );
/* create a basic temporary DOMDocument to copy nodes into */
$tmp=new DOMDocument;
$tmp->formatOutput=true;
$root=$tmp->createElement('root');
$tmp->appendChild( $root );
$tmp->saveXML();
/* Create the main DOMDocument to process the source XML */
$dom=new DOMDocument;
$dom->validateOnParse=false;
$dom->recover=true;
$dom->strictErrorChecking=false;
$dom->loadXML( $xml );
$errors = libxml_get_errors();
libxml_clear_errors();
/* were there errors with the XML? */
if( !empty( $errors ) ){
/* do stuff */
}
/*
create the XPath object and register the namespace so
we can query for nodes that use that namespace prefix
*/
$xp=new DOMXPath( $dom );
$xp->registerNamespace( 'air','http://www.travelport.com/schema/air_v48_0');
/* run the query to find nodes of interest */
$colaps=$xp->query('//air:AirPricingSolution');
if( $colaps->length > 0 ){
/*
For each node found create a
clone and add to the temp document
*/
foreach( $colaps as $aps ){
$clone=$tmp->importNode( $aps->cloneNode( true ), true );
$tmp->documentElement->appendChild( $clone );
}
}
/*
there is now a dcument with all cloned nodes which
can be saved or displayed or further manipulated
*/
printf( '<textarea cols=100 rows=20>%s</textarea>',$tmp->saveXML() );
update
В соответствии с абсолютно правильными комментариями по поводу использования фрагмента документа, а не всего документа - это более чистое решение - вот как это можно сделать.
libxml_use_internal_errors( true );
$dom=new DOMDocument;
$dom->validateOnParse=false;
$dom->recover=true;
$dom->strictErrorChecking=false;
$dom->loadXML( $xml );
$errors = libxml_get_errors();
libxml_clear_errors();
$tmp=$dom->createDocumentFragment();
$xp=new DOMXPath( $dom );
$xp->registerNamespace( 'air','http://www.travelport.com/schema/air_v48_0');
$colaps=$xp->query('//air:AirPricingSolution');
if( $colaps->length > 0 ){
foreach( $colaps as $aps ){
$clone=$aps->cloneNode( true );
$tmp->appendChild( $clone );
}
}
$var = $dom->saveXML( $tmp ); # play with $var
Чтобы выбрать конкретный узел на основе определенного атрибута, в данном случае Key
, вам нужно немного изменить базовое выражение XPath.
Рассмотреть эти узлы в XML
cherry
банан
яблоко
XPath для их поиска может выглядеть следующим образом:
$col=$xp->query( '//air:AirPricingSolution[ @Key="CherryRed" ]' );
Взгляните на этот превосходный XPath-лист