OTA XML standard: error on line 2 at column 1: Extra content at the end of the document XML to get POST in PHP

273 views Asked by At

I have two days trying to fix this error with this XML code:

    `<OTA_VehResRQ Version="1.00">
    <POS>
        <Source><RequestorID ID="22" Type="90"></RequestorID></Source>
    </POS>
    <BookingReferenceID>
        <UniqueID_Type ID="338964670"></UniqueID_Type>
    </BookingReferenceID>
    <VehResRQCore>
        <VehRentalCore PickUpDateTime="2017-01-10T10:00:00" ReturnDateTime="2017-01-11T16:00:00">
            <PickUpLocation LocationCode="88" ExtendedLocationCode="CUN01"></PickUpLocation>
            <ReturnLocation LocationCode="89" ExtendedLocationCode="CUN"></ReturnLocation>
        </VehRentalCore>
        <VehPref VendorCarType="MCMR">
            <VehClass>MCMR</VehClass>
            <VehType>Chevrolet Matiz</VehType>
        </VehPref>
        <RateQualifier VendorRateID="90" RateAuthorizationCode="51 || 52" PromotionCode=""/>
        <Customer>
            <Primary>
                <PersonName>
                    <NamePrefix>Mr</NamePrefix>
                    <GivenName>Carlos</GivenName>
                    <Surname>Gomez</Surname>
                </PersonName>
                <Telephone PhoneTechType="001.PTT" PhoneNumber="01 123 4567"></Telephone>
                <Telephone PhoneTechType="005.PTT" PhoneNumber="041 234 5678"></Telephone>
                <Email>
                    <Value>[email protected]</Value>
                </Email>
                <Address>
                    <CityName>Cancun</CityName>
                    <StateProv>Quintana Roo</StateProv>
                    <CountryName>New Zealand</CountryName>
                </Address>
            </Primary>
        </Customer>
        <Fees>
            <Fee Description="10% Airport fee" Purpose="049.VCP" Amount=""></Fee>
        </Fees>
        <VehicleCharges Purpose="022.VCP">
            <VehicleCharge CurrencyCode="USD" >
                <Calculation Quantity="4" UnitName="Day" UnitCharge="120" total="480"></Calculation>
                <TaxAmounts>
                    <TaxAmount Description="IVA Tax" TaxCode="IVA" Total=""></TaxAmount>
                </TaxAmounts>
            </VehicleCharge>
        </VehicleCharges>
        <TPA_Extensions>
            <SOE_ExtrasRequest>
                <Extra Code="1" Quantity="1" Amount="26.25" Period="11"></Extra>
                <Extra Code="2" Quantity="1" Amount="37.50" Period="NA"></Extra>
                <Extra Code="3" Quantity="1" Amount="90"    Period="NA"></Extra>
            </SOE_ExtrasRequest>
            <SOE_Comments>
                <Comment Name="optional info 1">
                    <Text>Any other relevant information such as flight no</Text>
                </Comment>
            </SOE_Comments>
        </TPA_Extensions>
    </VehResRQCore>
    <SpecificFlightInfoType>
        <FlightNumber>123</FlightNumber>
        <Airline>British airline</Airline>
    </SpecificFlightInfoType>
</OTA_VehResRQ>

`

I'm reading with this method:

`public function actionIndex()
    {
        if (isset($_REQUEST["XML"])) {
            $XML = $_REQUEST["XML"];
        } else {
            $XML = file_get_contents('php://input');
        }

        $xmlValidado = XMLReader::xml($XML);
        $xmlValidado->setParserProperty(XMLReader::VALIDATE, true);

       //header("Content-type: text/xml");
        require_once("Array2XML.php");

        if ($XML = simplexml_load_string($XML)) {
            $Action = $XML->getName();
            $POS = $XML->POS;
            $Type = $POS->Source->RequestorID->attributes()->Type;
            $UserName = $POS->Source->RequestorID->attributes()->ID;
            $Password = $POS->Source->RequestorID->attributes()->MessagePassword;
            header("Content-type: text/xml");
            $this->{$Action}($XML);
        } else {
            header("Content-type: text/xml");
            $Results = array();
            $Results['@attributes'] = array(
                'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
                'lastUpdated' => date('c'),
            );
            $Results["ErrorMessage"] = utf8_encode("XML Invalido!");
            $xml = Array2XML::createXML('Error', $Results);
            echo str_replace("\n", "", (trim($xml->saveXML())));
        }
        exit();

    }`

And I load a method called:

public function OTA_VehResRQ($XML){
        $Results = array();
        $Results['@attributes'] = array(
            'Version' => '1.00',
            'TimeStamp' => date('c')
        );


        $ctTextLoc = self::CT_TEXTLOC;
        $ctLocations = self::CT_LOCATIONS;
        $ctEstatus = self::CT_ST;


        $RateId = (int)$XML->POS->Source->RequestorID->attributes()->ID;
        $DateIn = (string)$XML->VehResRQCore->VehRentalCore->attributes()->PickUpDateTime;
        $DateOut = (string)$XML->VehResRQCore->VehRentalCore->attributes()->ReturnDateTime;
        $locpu_text = (string)$XML->VehResRQCore->VehRentalCore->PickUpLocation->attributes()->ExtendedLocationCode;
        $locdo_text = (string)$XML->VehResRQCore->VehRentalCore->ReturnLocation->attributes()->ExtendedLocationCode;

        $salutation = (string)$XML->VehResRQCore->Customer->Primary->PersonName->NamePrefix;
        $nombre     = (string)$XML->VehResRQCore->Customer->Primary->PersonName->GivenName;
        $apellidos  = (string)$XML->VehResRQCore->Customer->Primary->PersonName->Surname;
        $email      = (string)$XML->VehResRQCore->Customer->Primary->Email;
        $telefono   = ((string)$XML->VehResRQCore->Customer->Primary->Telephone->attributes()->PhoneTechType == '001.PTT')?(string)$XML->VehResRQCore->Customer->Primary->Telephone->attributes()->PhoneNumber : '';
        $ciudad     = (string)$XML->VehResRQCore->Customer->Primary->Address->CityName;
        $celular    = ((string)$XML->VehResRQCore->Customer->Primary->Telephone->attributes()->PhoneTechType == '005.PTT')?(string)$XML->VehResRQCore->Customer->Primary->Telephone->attributes()->PhoneNumber : '';
        $estado     = (string)$XML->VehResRQCore->Customer->Primary->Address->StateProv;
        $pais       = (string)$XML->VehResRQCore->Customer->Primary->Address->CountryName;

        $datePickup = date("Y-m-d", strtotime($DateIn));
        $dateDropoff = date("Y-m-d", strtotime($DateOut));
        $referencia         = (string)$XML->BookingReferenceID->UniqueID_Type->attributes()->ID;
        $tarifa_grupo       = (string)$XML->VehResRQCore->RateQualifier->attributes()->RateAuthorizationCode;
        $web_flota_acriss   = (string)$XML->VehResRQCore->VehPref->VehClass;
        $web_flota_similar  = (string)$XML->VehResRQCore->VehPref->VehType;
        $loc_pickup         = (int)$XML->VehAvailRQCore->VehRentalCore->PickUpLocation->attributes()->LocationCode;
        $loc_dropoff        = (int)$XML->VehAvailRQCore->VehRentalCore->ReturnLocation->attributes()->LocationCode;
        $loc_pickup_text    = $ctTextLoc["$locpu_text"];
        $loc_dropoff_text   = $ctTextLoc["$locdo_text"];
        $pickup_time_hr     = date("H", strtotime($DateIn));
        $pickup_time_min    = date('i', strtotime($DateIn));
        $dropoff_time_hr    = date("H", strtotime($DateOut));
        $dropoff_time_min   = date('i', strtotime($DateOut));
        $costo_dias         = (int)$XML->VehResRQCore->VehicleCharges->Vehiclecharge->Calculation->attributes()->Unitcharge;
        $costo_semana       = 0;
        $costo_horas        = 0;
        $total_dias         = (int)$XML->VehResRQCore->VehicleCharges->Vehiclecharge->Calculation->attributes()->Quantity;
        $total_semanas      = 0;
        $total_horas        = 0;
        $total_renta        = (int)$XML->VehResRQCore->VehicleCharges->Vehiclecharge->Calculation->attributes()->total;
        $total_extras       = 0;
        $imp_iva            = (int)$XML->VehResRQCore->VehicleCharges->Vehiclecharge->TaxAmounts->TaxAmount->attributes()->Total;
        $imp_aepto          = (float)$XML->VehResRQCore->Fees->Fee->attributes()->Amount;
        $total_total        = "";
        $moneda             = (string)$XML->VehResRQCore->VehicleCharge->attributes()->CurrencyCode;
        $extras             = serialize($XML->VehresRQCore->TPA_Extensions->SOE_ExtrasRequest);
        $st                 = "";
        $flight_number      = (string)$XML->SpecificFlightInfoType->FlightNumber;
        $flight_airline     = (string)$XML->SpecificFlightInfoType->Airline;
        $comments           = (string)$XML->VehresRQCore->TPA_Extensions->SOE_Comments->Comment->text;

        foreach ($XML->VehresRQCore->TPA_Extensions->SOE_ExtrasRequest->attributes()->Amount as $item => $value){
            $total_extras += $value;
        }

        $rInsert = new Reservacion;
        $cInsert = new ReservacionCliente;

        $cInsert->salutation = (string)$salutation;
        $cInsert->nombre = (string)$nombre;
        $cInsert->apellidos = (string)$apellidos;
        $cInsert->email = (string)$email;
        $cInsert->telefono = (string)$telefono;
        $cInsert->celular = (string)$celular;
        $cInsert->ciudad = (string)$ciudad;
        $cInsert->pais = (string)$pais;
        $cInsert->estado = (string)$estado;
        $cInsert->save();

        $ClienteID = $cInsert->cliente_id;

        /*if ($r["total_horas"] > 0) {
            $horas = (int) ($r["total_horas"] / $r["costo_horas"]);
        } else {
            $horas = 0;
        }*/
        $rInsert->referencia = (string)$referencia;
        $rInsert->tarifa_grupo = $tarifa_grupo;
        $rInsert->web_flota_acriss = (string) $web_flota_acriss;
        $rInsert->web_flota_similar = $web_flota_similar;
        $rInsert->web_sitio_id = 5;
        $rInsert->prefijo = "RCC";
        $rInsert->code = self::getNextId('code','web_reservacion',$condicion = array('prefijo'),$parametro = array('RCC') );
        $rInsert->web_cliente_id = $ClienteID;
        $rInsert->fecha = date("Y-m-d H:i:s");
        $rInsert->pickup = $datePickup;
        $rInsert->dropoff = $dateDropoff;
        $rInsert->loc_pickup = $ctLocations[(string) $loc_pickup];
        $rInsert->loc_dropoff = $ctLocations[(string) $loc_dropoff];
        $rInsert->loc_pickup_text = $loc_pickup_text;
        $rInsert->loc_dropoff_text = $loc_dropoff_text;
        $rInsert->pickup_time_hr = $pickup_time_hr;
        $rInsert->dropoff_time_hr = $dropoff_time_hr;
        $rInsert->pickup_time_min = $pickup_time_min;
        $rInsert->dropoff_time_min = $dropoff_time_min;
        $rInsert->costo_dias = $costo_dias;
        $rInsert->costo_semana = $costo_semana;
        $rInsert->costo_horas = $costo_horas;
        $rInsert->total_dias = (int)$total_dias;
        $rInsert->total_semanas = (int) $total_semanas;
        $rInsert->total_horas = (int) $total_horas;
        $rInsert->total_renta = $total_renta;
        $rInsert->total_extras = $total_extras;
        $rInsert->iva = $imp_iva;
        $rInsert->impuesto_aeropuerto = $imp_aepto;
        $rInsert->extras = serialize($extras);
        $rInsert->total = $total_total;
        $rInsert->moneda = $moneda;
        $rInsert->estatus = $ctEstatus[$st];
        $rInsert->flight_number = $flight_number;
        $rInsert->flight_airline = $flight_airline;
        $rInsert->dominio = "Rental Cars";
        $rInsert->agente_callcenter = 0;
        $rInsert->comments = $comments;

        if((string)$XML->VehResRQCore->VehicleCharges->attributes()->Purpose == '022.VCP'){
            $rInsert->pagada = 1;
            $rInsert->pago_fecha = date("Y-m-d H:i:s");
            $rInsert->pago_detalle = $total_renta;
            $rInsert->pago_observacion = 'Prepago de la renta, pendiente los adicionales';
        }

        if (!$rInsert->save()) {
            $Results['Success'] = 'false';
            $Results['VehResRSCore']['@attributes'] = array(
                'ReservationStatus' => 'Not Committed'
            );
        } else {
            $Results['Success'] = 'true';
            $Results['VehResRSCore']['@attributes'] = array(
                'ReservationStatus' => 'Committed'
            );
            $Results['VehResRSCore']['VehReservation']['VehSegmentCore']['ConfID']['@attributes'] = array(
                'Type' => '014.UIT',
                'ID'   => 'RCC-' . $rInsert->code
            );
        }

        $xml = Array2XML::createXML('OTA_VehResRS', $Results);
        echo str_replace("\n", "", (trim($xml->saveXML())));
    }

Is so weird because with another XML script works pretty well exe:

`<OTA_VehLocSearchRQ Version="1.00">
    <POS>
        <Source>`enter code here`
            <RequestorID ID="22"></RequestorID>
        </Source>
    </POS>
</OTA_VehLocSearchRQ>`

To the method:

public function OTA_VehLocSearchRQ($XML)
    {
        $Results = array();
        $Results['@attributes'] = array(
            'Version' => '1.00',
            'TimeStamp' => date('c')
        );

        if ($XML->POS->Source->RequestorID->attributes()->ID == 22) { // Sistema 22 = Rental Cars
            $XML->POS->Source->RequestorID->attributes()->ID = 16; //Proveedor 16 = Rental Cars
        }

        if (isset($XML->VehLocSearchCriterion)) {
            $Results["Success"] = true;
            $Results["VehMatchedLocs"] = array();

            $Locaciones = Yii::app()->db->createCommand()
                ->select('*, c.Name as Pais, c.Code2 as Country2L')
                ->from('cr_locaciones')
                ->join("Country c", "c.Code = locacion_pais")
                ->join("City", "ID = locacion_ciudad")
                ->where("locacion_proveedor = :proveedor AND locacion_id = :codigo", array(":proveedor" => (string)$XML->POS->Source->RequestorID->attributes()->ID, ":codigo" => $XML->VehLocSearchCriterion->RefPoint))
                ->queryAll();
        } else {
            $Results["Success"] = true;
            $Results["VehMatchedLocs"] = array();

            $Locaciones = Yii::app()->db->createCommand()
                ->select('*, c.Name as Pais, c.Code2 as Country2L')
                ->from('cr_locaciones')
                ->join("Country c", "c.Code = locacion_pais")
                ->join("City", "ID = locacion_ciudad")
                ->where("locacion_proveedor = :proveedor", array(":proveedor" => $XML->POS->Source->RequestorID->attributes()->ID))
                ->queryAll();


        }

        if (sizeof($Locaciones) > 0) {
            $Results["VehMatchedLocs"]["VehMatchedLoc"] = array();


            foreach ($Locaciones as $l) {
                $lInfo = array(
                    "LocationDetail" => array(
                        "@attributes" => array(
                            "Code" => $l["locacion_id"],
                            "Name" => $l["locacion_nombre_en"],
                            "AtAirport" => (($l["locacion_tipo"] == 2) ? true : false),
                            "CodeContext" => "PickupLocation",

                        ),
                        "Address" => array(
                            "AddressLine" => utf8_encode($l["locacion_direccion_linea_1"]),
                            "CityName" => utf8_encode($l["Name"]),
                            "PostalCode" => $l["locacion_cp"],
                            "CountryName" => array(
                                "@attributes" => array("Code" => $l["Country2L"]),
                                "@value" => $l["Pais"],
                            ),
                        ),
                        "Telephone" => array(
                            "@attributes" => array(
                                "PhoneNumber" => $l["locacion_telefono"],
                                "FormattedInd" => false,
                            ),
                        ),
                    )
                );

                array_push($Results["VehMatchedLocs"]["VehMatchedLoc"], $lInfo);
            }

        } else {
            $Results["Success"] = false;
        }


        $xml = Array2XML::createXML('OTA_VehLocSearchRS', $Results);
        echo str_replace("\n", "", (trim($xml->saveXML())));
    }

Someone can give tips, I have researched and I could not find anything.

A million thanks.

1

There are 1 answers

0
Carlos M Gomez On BEST ANSWER

I found the mistake, the problem was the "foreach" I was not iterating the array pretty well.

foreach ($XML->VehResRQCore->Customer->Primary->Telephone as $Telephone) { switch((string) $Telephone['PhoneTechType']) { // Obtener los atributos como índices del elemento case '001.PTT': $telefono = $Telephone['PhoneNumber']; break; case '005.PTT': $celular = $Telephone['PhoneNumber']; break; } }

To serialize the extras:

foreach ($XML->xpath('//Extra') as $Extras) { array_push( $extras,(string)$Extras['Code'],(string)$Extras['Amount'],(string)$Extras['observations']); }

Is the first time I work with XML... anyway, I got it! I answer my question if is helpful to another one!