# vcf file zu xml konvertieren



## supersalzi (7. Juni 2007)

Hey,

Ich würde gern den vcf File (bzw. eine spezielle Textdatei) mittels PHP so umformen, dass eine xml Datei herauskommt. 

Das arbeiten mit Textdateien ist mir nicht ganz neu, aber ich scheitere schon daran, wie ich die Datei auslesen soll; Zeilenweise, als String oder als Array um sie sinnvoll weiter zu zerlegen.

Mein erster Versuch war mit explode("END:VCARD", $datei); aber ich kam mit den teilen dann nicht klar.

Wie könnte man an so etwas heran gehen?

Hier mal die Ausgangsdatenform:

```
BEGIN:VCARD
VERSION:2.1
N:Mustermann;Max
TEL;WORK:222222222
TEL;HOME:111111111111
EMAIL;INTERNET;PREF:mail@adresse
URL;WORK:www.was.o
TEL;CELL:00000000000
TEL;FAX:88888888
NOTE:Info
ORG:Firma
TITLE:Hr.
TEL:9999999999
ADR;HOME:;;Street;City;Bundesland;01234;Germany
END:VCARD
```

soll zu folgendem werden:

```
<person>
	<name>Max</name>
	<surname>Mustermann</surname>
	<tel>
		<cell>00000000000</cell>
		<home>111111111111</home>
		<work>222222222</work>
		<other>9999999999</other>
	</tel>
	<fax>88888888</fax>
	<address>
		<title>Hr.</title>
		<company>Firma</company>
		<street>Street</street>
		<city>City</city>
		<state>Bundesland</state>
		<zipcode>01234</zipcode>
		<country>Germany</country>
	</address>
	<note>Info</note>
</person>
```

vielen Dank, salzi


----------



## Flex (7. Juni 2007)

Da die VCards wahrscheinlich immer den selben Aufbau haben (?) würde ich einfach per [phpf]file[/phpf] einlesen und mit [phpf]explode[/phpf] anhand des ";" trennen oder mit [phpf]substr[/phpf] abschneiden.
Danach bequem eine XML Datei erstellen (SimpleXML?) oder Dennis' XML Klasse.


/edit:

Gerade noch mal gesucht und dabei bin ich auf diese Klasse gestoßen:
IMC Objects


			
				Description hat gesagt.:
			
		

> This is a package of classes that are meant to provide an interface to access  data of iCalendar and vCard files defined by the IMC (Internet Mail Consortium).
> 
> The library can read and write files with the formats defined by IMC.


----------



## andy72 (7. Juni 2007)

Eine bessere Möglichkeit bietet das von PEAR bereitgestellte vCard-Modul, dass man sich auch schnell umschreiben kann,sofern kein PEAR vorhanden ist (auf einigen Servern ist das leider so): Einfach die Aufrufe für PEAR rausnehmen (sind nur ein Paar um Fehler darzustellen) und dann kann man das auch "so" nutzen.

vCard von PEAR bietet problemloses generieren und auslesen von vCards nach standardgerechten Inhalten, die Benutzung läuft wie ein ini-File


----------



## Flex (7. Juni 2007)

Ich finde das PEAR Paket ehrlich gesagt nicht so elegant, da es unglaublich verschachtelte Arrays zurückgibt.


----------



## supersalzi (7. Juni 2007)

Hi Felix,

Danke für das Suchen nach der Class aber mir geht es mehr ums selbst machen und verstehen, sorry.

Ich bin der Ansicht die Vcards sind nicht immer gleich, das heißt irgendwie schon, aber nicht ausgefüllte Einträge fehlen einfach. Hier nochmal ein Beispiel eines nicht vollständigen Kontaktes:

```
BEGIN:VCARD
VERSION:2.1
N:;Anna
TEL;WORK:071234567
TEL;HOME:071234567
EMAIL;INTERNET;PREF:anna.s@t-online.de
TEL;CELL:071234567
ADR;HOME:;;Hohe Str. 100;Bochum;;0134;
END:VCARD
```


----------



## andy72 (7. Juni 2007)

Der Aufbau ist aber prinzipiell der gleiche in jeder Card.
Ich würde das so machen: File einlesen, dann die Zeilen nach "\n" trennen und dann auswerten. Muss man halt sehen, welche Optionen/Werte in einer vCard erlaubt sind bzw vorkommen können und entsprechend nach Felix' Vorschlag weiter nach ";" trennen


----------



## Flex (7. Juni 2007)

supersalzi hat gesagt.:


> Hi Felix,
> 
> Danke für das Suchen nach der Class aber mir geht es mehr ums selbst machen und verstehen, sorry.



Dann wäre doch die Klasse der perfekte Platz um anzuschauen, wie die Klasse die Datei einliest, die Daten trennt, usw. um es dann in einer eigenen Form umzusetzen bzw. an deine Bedürfnisse anzupassen?


----------



## supersalzi (7. Juni 2007)

da hast du auch wieder recht...

ich muss eh mal sehen, denn ich kann mir es noch nicht richtig denken, viele schleifen wahrscheinlich...

aber danke erstmal, salzi


----------



## RS9999 (8. Juni 2007)

Solltest Du die "DOM XML Erweiterung" installiert haben,
könntest Du das auch so machen:

Achtung: Diese Erweiterung ist EXPERIMENTELL. 


```
<?php 

$doc = new DOMDocument('1.0');

$doc->formatOutput = true;

$file = file('vcf_card.txt');

for($i=0;$i < count($file);$i++)
{
   $a[] = explode(':',$file[$i]);
   $b[] = explode(';',$a[$i][1]);
}

$root = $doc->createElement('person');
$root = $doc->appendChild($root);

$name = $doc->createElement('name');
$name = $root->appendChild($name);

$vname = $doc->createTextNode($b[2][1]);
$vname = $name->appendChild($vname);

$surname = $doc->createElement('surname');
$surname = $root->appendChild($surname);

$nname = $doc->createTextNode($b[2][0]);
$nname = $surname->appendChild($nname);

// u.s.w 

//Daten in xml-Datei speichern!
$doc->save("test.xml");
```
?>


----------



## Flex (8. Juni 2007)

RS9999 hat gesagt.:


> Solltest Du die "DOM XML Erweiterung" installiert haben,
> könntest Du das auch so machen:
> 
> Achtung: Diese Erweiterung ist EXPERIMENTELL.



Also die DOM XML Erweiterung ist keinesfalls mehr experimentell, sondern sogar "überholt" da sie in PHP5 nicht mehr vorhanden ist.
Falls man in PHP5 trotzdem noch DOM nutzen will, gibt es die DOM Extension:
DOM Functions

Allerdings gibt es in PHP5 schönere Funktionen wie die von SimpleXML.


----------



## RS9999 (8. Juni 2007)

> Zitat von Felix Jacobi:
> Also die DOM XML Erweiterung ist keinesfalls mehr experimentell, sondern sogar "überholt" da sie in PHP5 nicht mehr vorhanden ist.
> Falls man in PHP5 trotzdem noch DOM nutzen will, gibt es die DOM Extension:
> DOM Functions


Bitte um Entschuldigung wenn ich da etwas falsches wiedergegeben habe.
Gut das es so aufmerksame User gibt.
Meine Informationen zu der DOM XML Funktion habe ich aus dem Original PHP Handbuch.

Eigentlich ging es mir auch mehr darum *supersalzi *...





> ich muss eh mal sehen, denn ich kann mir es noch nicht richtig denken, viele schleifen wahrscheinlich...


zu wiederlegen, dass er mit vielen schleifen arbeiten muss, sondern das alles
mit einer Schleife zu erledigen ist. Ob er dazu *SimpleXML* oder *fopen* oder auch *DOM
XML* benutzt ist Seine Sache.


----------



## supersalzi (11. Juni 2007)

Jetzt stehe ich vor dem Problem, dass ich noch eine Synchronisations-Funktion bräuchte.

Ich habe es geschafft ein Script zu schreiben, was erstmal eine vCard in ein xml format formatiert. (Vermutlich ist es katastrophal (mein erster OOP versuch) und SimpleXML könnte das bestimmt besser.)

Jetzt gehe ich aber davon aus, dass es die XML Datei schon gibt und zwar mit mehr Daten als in der neu einzulesenden vCard gespeichert sind. (z.B. speichert mein Handy keine Geburtstage).
Also müssten die Datensätze abgeglichen werden und nur geänderte Einträge in die XML Datei übernommen werden. Nur für noch nicht vorhandene Kontakte müsste der XML Code neu erzeugt werden.


Kann mir dafür jemand einen Ratschlag geben?

Hier nochmal mein Code:

```
<?php

class person {
	
	public $uid;
	
	public $name;
	public $surname;
	public $fullname;
	public $add_name;
	public $honorPre;
	public $honorSuf;
	public $sortstring;
	
	public $tel_cell;
	public $tel_home;
	public $tel_work;
	public $tel_fax;
	public $tel_other;

	
	public $postbox;
	public $ext_addr;
	public $street;
	public $city;
	public $state;
	public $zipcode;
	public $country;
	
	public $org;
	public $email;
	public $url;
	public $birthday;
	public $note;


public function set_person_uid($uid){
	$this -> uid = $uid;
}

public function set_person_data($vCard){


	$zeile = explode("\n", $vCard);
	
	for($i = 0; $i < count($zeile); $i++){
		$eintrag = explode(":", $zeile[$i]);
				
		if( $eintrag[0] == "N" ){
			$names = explode(";", $eintrag["1"]);
			
			$this -> surname = $names[0];
			$this -> name = $names[1];
			$this -> add_name = $names[2];
			$this -> honorPre = $names[3];
			$this -> honorSuf = $names[4];
			$this -> sortstring = $names[1];
		
		}elseif( $eintrag[0] == "FN" ){	
			$this -> fullname = $eintrag[1];
			
		}elseif( eregi("TEL", $eintrag[0]) ){
			
			if(  eregi("FAX", $eintrag[0]) ){
				$this -> tel_fax = $eintrag[1];
			}elseif( eregi("HOME", $eintrag[0]) and !eregi("FAX", $eintrag[1]) ){
				$this -> tel_home = $eintrag[1];
			}elseif( eregi("WORK", $eintrag[0]) and !eregi("FAX", $eintrag[1]) ){
				$this -> tel_work = $eintrag[1];
			}elseif(  eregi("CELL", $eintrag[0]) ){
				$this -> tel_cell = $eintrag[1];
			}elseif( !eregi("FAX", $eintrag[0]) ){
				$this -> tel_other = $eintrag[1];
			}
		
		}elseif( eregi("ADR", $eintrag[0]) ){
			$adr = explode(";", $eintrag["1"]);
			$this -> postbox = $adr[0];
			$this -> ext_addr = $adr[1];
			$this -> street = $adr[2];
			$this -> city = $adr[3];
			$this -> state = $adr[4];
			$this -> zipcode = $adr[5];
			$this -> country = $adr[6];
			
		}elseif( eregi("EMAIL", $eintrag[0]) ){
			
			if( eregi("PREF", $eintrag[0]) and eregi("INTERNET", $eintrag[0]) ){
				$email_pref = $eintrag[1];
			}else{
				$email_nonpref = $eintrag[1];
			}
			
			if( !empty($email_pref) ){
				$email = $email_pref;
			}else{
				$this -> email = $email_nonpref;
			}
							
		}elseif( eregi("URL", $eintrag[0])){
			$this -> url = $eintrag[1].":".$eintrag[2]; 
		}elseif( $eintrag[0] == "BDAY"){
			$this -> birthbday = $eintrag[1];
		}elseif( $eintrag[0] == "NOTE" ){
			$this -> note = $eintrag[1];
		}elseif( $eintrag[0] == "ORG" ){
			$this -> org = $eintrag[1];
		}
	}
}
	
public function export_xml(){

$xml = "
<person uid=\"".$this -> uid."\" >\n
<class></class>\n
<fullname>".$this -> fullname."</fullname>\n
<name>".$this -> name."</name>\n
<surname>".$this -> surname."</surname>\n
<sort-string>".$this -> sortstring."</sort-string>\n
<tel>\n
	<cell>".$this -> tel_cell."</cell>\n
	<home>".$this -> tel_home."</home>\n
	<work>".$this -> tel_work."</work>\n
	<other>".$this -> tel_other."</other>\n
	<fax>".$this -> tel_fax."</fax>\n
</tel>\n

<address>\n
	<postbox>".$this -> postbox."</postbox>\n
	<extaddr>".$this -> ext_addr."</extaddr>\n
	<street>".$this -> street."</street>\n
	<city>".$this -> city."</city>\n
	<state>".$this -> state."</state>\n
	<zipcode>".$this -> zipcode."</zipcode>\n
	<country>".$this -> country."</country>\n
</address>\n
<org>".$this -> org."</org>\n

<note>".$this -> note."</note>\n
<birthday>".$this -> birthday."</birthday>\n
</person>\n";

return $xml;
}

}


$file = "address.txt";
$datei = implode ('', file ($file));
$datei = "\n".$datei;
$card  = explode("END:VCARD", $datei);


for($a = 0; $a < count($card); $a++){


$person[$a] = new person;
$person[$a] -> set_person_data($card[$a]);
$person[$a] -> set_person_uid($a);
$xml_person[$a] = $person[$a] -> export_xml();

echo $xml_person[$a];
}
?>
```
freu mich auch über hinweise zum Code.

vielen Dank, Salzi


----------

