PHP Copy xml From one XML file to another

127 views Asked by At

I'm very new to coding and have been thrown in at the depend but learning slowly! I have managed to create a script in PHP that logs into a property feed website in order to obtain a list of current properties listed by a seller.

This is a 3 step process to get to the final XML property file. (Step:1 authenticates, Step:2 creates an XML file of all properties by ID and Step:3 provides an XML file containing all property specific details based on a property ID obtained in step 2.

Here is the current script for Step:3:

        public function getProperties($client_id) {
        $token_storage = fopen('token.txt', 'r') or die("Unable to open file!");
        $token = trim(fread($token_storage,filesize("token.txt")));
        fclose($token_storage);
        $url = "http://webservices.vebra.com/export/".$this->_datafeedid."/v".$this->_version."/branch/{$client_id}/property";
        
        $headers = array (
            "Content-type: application/xml",
            "Connection: close",
            "Authorization: Basic ".base64_encode($token)
        );
    
        $ch = curl_init(); 
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

        
        
        $all_properties_id_only = curl_exec($ch);
        

        file_put_contents ('./all_properties_id_only.xml', $all_properties_id_only); 
        
        //return $data;

            
 $xml=simplexml_load_file("./all_properties_id_only.xml") or die("Error: Cannot create object");
 $count = 0;
 foreach($xml->children() as $property) {
 $count = $count + 1;
 echo  "count = " .$count." property = ".$property->prop_id."<br>" ;

  
  $url = "http://webservices.vebra.com/export/".$this->_datafeedid."/v".$this->_version."/branch/{$client_id}/property/{$property->prop_id}";
        echo $property->prop_id . '<br>';

        $headers = array (
            "Content-type: application/xml",
            "Connection: close",
            "Authorization: Basic ".base64_encode($token)
        );
        
        $ch = curl_init(); 
        curl_setopt($ch, CURLOPT_URL,$url);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        
    $all_properties_full = curl_exec($ch);
        
    file_put_contents ('./all_properties_full.xml', $all_properties_full, FILE_APPEND); 
        //return $data;


}
}

The problem I have is that the final Step:3 generated XML file returned from the property server contains the XML data <?xml version="1.0" encoding="utf-8"?> so when I append each property to the 'all_properties_full.xml' XML file it becomes invalid XML. (It also does not have a required tag <properties></properties>

I figured that I could use a template XML file (properties_template.xml) with the initial tags required and then iterate over 'all_properties_full.xml' to produce the final XML file (merged.xml) with the correct structure and details of each property.

I found something similar here on StackOverflow but could not get it to work due to the following errors:

PHP Warning: DOMDocument::load(): XML declaration allowed only at the start of the document in /home/ PHP Warning: DOMDocument::load(): Extra content at the end of the document in /home/ PHP Fatal error: Uncaught Error: Call to undefined method DOMNodeList::property() in /home/

        $doc1 = new DOMDocument();
        $doc1->load('./properties_template.xml');

        $doc2 = new DOMDocument();
        $doc2->load('./all_properties_full.xml');
        

$target = $doc1->getElementsByTagName('properties')->property(0);

// iterate over 'property' elements of document 2
$properties2 = $doc2->getElementsByTagName('property');
for ($i = 0; $i < $properties2->length; $i ++) {
    $properties2 = $properties2->property($i);

    // import/copy item from document 2 to document 1
    $property1 = $doc1->importNode($properties2, true);

    // append imported item to document 1 'res' element
    $target->appendChild($property1);

}
$doc1->save('merged.xml'); //edited -added saving into xml file 

Step:3 XML data that is returned from the property server is in this format:

<?xml version="1.0" encoding="utf-8"?>
<property xsi:noNamespaceSchemaLocation="http://webservices.vebra.com/export/xsd/v11/exportapi.xsd" id="00000001" propertyid="12345678" system="A" firmid="0001" branchid="1" database="1" featured="0">
<reference>
</reference>
<address>
</address>
<price qualifier="Guide Price" currency="GBP" display="yes">250000</price>
<rentalfees/>
<lettingsfee/>
<rm_qualifier>0</rm_qualifier>
</property>

This is the properties_template.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<properties>
<property>ADDITIONAL PROPERTY DETAILS HERE</property>
</properties>

What I am ultimately trying to achieve with 'all_properties_full.xml' is the following structure:

<?xml version="1.0" encoding="utf-8"?>
<properties>
<property xsi:noNamespaceSchemaLocation="http://webservices.vebra.com/export/xsd/v11/exportapi.xsd" id="1" propertyid="00000001" system="A" firmid="0001" branchid="1" database="1" featured="0">
<reference>
</reference>
<address>
</address>
<price qualifier="Guide Price" currency="GBP" display="yes">250000</price>
<rentalfees/>
<lettingsfee/>
<rm_qualifier>0</rm_qualifier>
</property>

<property xsi:noNamespaceSchemaLocation="http://webservices.vebra.com/export/xsd/v11/exportapi.xsd" id="2" propertyid="00000002" system="A" firmid="0001" branchid="1" database="1" featured="0">
<reference>
</reference>
<address>
</address>
<price qualifier="Guide Price" currency="GBP" display="yes">250000</price>
<rentalfees/>
<lettingsfee/>
<rm_qualifier>0</rm_qualifier>
</property>
</properties>

I'm also completely open to achieving this another way if there is a simpler/more efficient way of achieving the final XML file.

Thank you for reading this far!

SONewb

0

There are 0 answers