|
FirstLook
Consider the following class hierarchy: class Person {
/** @XmlElement(string, first-name) */
private $firstName;
/** @XmlElement(string, last-name) */
private $lastName;
/** @XmlElement(date, birth-date) */
private $birthDate;
// getters and setters are skipped for brevity
}
abstract class Vehicle {
/** @XmlAttribute */
private $name;
/** @XmlElement */
private $description;
/** @XmlElement(Person) */
private $owner;
// getters and setters are skipped for brevity
}
class Car extends Vehicle {
/** @XmlAttribute(double) */
private $liter;
/** @XmlAttribute(int) */
private $cylinder;
/** @XmlAttribute(bool, automatic-transmission) */
private $automaticTransmission;
// getters and setters are skipped for brevity
}
class Boat extends Vehicle {
/** @XmlAttribute(int) */
private $deadweight;
// getters and setters are skipped for brevity
}
class Bike extends Vehicle {
/** @XmlElement(string, feature) */
public $features = array();
}
/** @XmlRoot(garage) */
class Garage {
/** @XmlAttribute(int) */
private $capacity;
/**
* @XmlElement(Car, car)
* @XmlElement(Boat, boat)
* @XmlElement(Bike, bicycle)
*/
private $vehicles;
function __construct() {
$this->vehicles = new ArrayObject();
}
// getters and setters are skipped for brevity
}There are the abstract Vehicle and three concrete vehicles: a Car, a Boat and a Bike. A vehicle belongs to a Person, and all of them are put into a Garage. I hope you'll excuse my fantasy of placing a sea ship there :) Next let's create some fancy instances of them: $carmack = new Person();
$carmack->setFirstName("John");
$carmack->setLastName("Carmack");
$carmack->setBirthDate(new DateTime("Aug 20, 1970"));Carmack was the lead programmer of the id computer games Wolfenstein 3D, Doom, Quake. A lot of thanks to him! $gump = new Person();
$gump->setFirstName("Forrest");
$gump->setLastName("Gump");
$gump->setBirthDate(new DateTime("1944-06-06"));His momma always said, "Life was like a box of chocolates. You never know what you're gonna get." $me = new Person();
$me->setFirstName("Alex");Oh, it's just me. $ferrari = new Car();
$ferrari->setName("Ferrari F50");
$ferrari->setCylinder(12);
$ferrari->setLiter(4.7);
$ferrari->setAutomaticTransmission(false);
$ferrari->setOwner($carmack);
$ferrari->setDescription( "The F50 was introduced in 1995 to celebrate the company's 50th anniversary.");For John Carmack, the idea of fancy offices is counterintuitive. "Most people would consider my twin turbo Ferrari F50 a fair amount of celebration," he says in response to Romero's comments. $bike = new Bike();
$bike->setName("Avalanche 1.0 Disc");
$bike->setDescription("The Avalanche 1.0 is for recreational riders looking for a mid-level mountain bike.");
$bike->features[] = "Frame: GT NEW Triple Triangle design 6061 butted aluminum";
$bike->features[] = "Tires: Kenda Nevegal, 26 x 2.10";
$bike->features[] = "Brakes: Tektro Auriga comp, hydraulic";
$bike->features[] = "Fork: Rock Shox Dart 3";
$bike->features[] = "Chain: Shimano HG-53 Nine Speed";
$bike->setOwner($me);This is my bike! $taxi = new Car();
$taxi->setName("Peugeot 406");
$taxi->setAutomaticTransmission(true);
$taxi->setDescription("In Taxi 3, the 406 is further upgraded to be able to travel in icy terrain.");Samy Naceri's transport. But I'm not sure about automatic... It's just for example. $boat = new Boat();
$boat->setName("Jenny");
$boat->setDescription("Shrimp boat. After the area was hit by Hurricane Carmen, Forrest's boat was the only one left standing.");
$boat->setDeadweight(200);
$boat->setOwner($gump);"If you're ever a shrimp boat captain, that's the day I'm an astronaut" (Lt. Dan) $garage = new Garage();
$garage->setCapacity(5);
$garage->getVehicles()->append($ferrari);
$garage->getVehicles()->append($bike);
$garage->getVehicles()->append($taxi);
$garage->getVehicles()->append($boat);Now, everything is in its right place and we're ready for serialization. require_once "path/to/lexa-xml-serialization.php";
use Lexa\XmlSerialization\XmlSerializer;
$dom = XmlSerializer::serialize($garage);That's it. $dom->formatOutput = true; $dom->saveXML() The two above lines will produce the following XML markup: <?xml version="1.0"?>
<garage capacity="5">
<car liter="4.7" cylinder="12" automatic-transmission="false" name="Ferrari F50">
<description>The F50 was introduced in 1995 to celebrate the company's 50th anniversary.</description>
<owner>
<first-name>John</first-name>
<last-name>Carmack</last-name>
<birth-date>1970-08-20</birth-date>
</owner>
</car>
<bicycle name="Avalanche 1.0 Disc">
<feature>Frame: GT NEW Triple Triangle design 6061 butted aluminum</feature>
<feature>Tires: Kenda Nevegal, 26 x 2.10</feature>
<feature>Brakes: Tektro Auriga comp, hydraulic</feature>
<feature>Fork: Rock Shox Dart 3</feature>
<feature>Chain: Shimano HG-53 Nine Speed</feature>
<description>The Avalanche 1.0 is for recreational riders looking for a mid-level mountain bike.</description>
<owner>
<first-name>Alex</first-name>
</owner>
</bicycle>
<car automatic-transmission="true" name="Peugeot 406">
<description>In Taxi 3, the 406 is further upgraded to be able to travel in icy terrain.</description>
</car>
<boat deadweight="200" name="Jenny">
<description>Shrimp boat. After the area was hit by Hurricane Carmen, Forrest's boat was the only one left standing.</description>
<owner>
<first-name>Forrest</first-name>
<last-name>Gump</last-name>
<birth-date>1944-06-06</birth-date>
</owner>
</boat>
</garage>Parsing it back to objects also doesn't require much effort: $garage2 = XmlSerializer::unserialize($dom, "Garage"); Finally you may want to generate an XML Schema (XSD) for your classes: $schema = XmlSerializer::generateSchema("Garage");
$schema->formatOutput = true;
$xml = $schema->saveXML();The output will be: <?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="garage" type="Garage-Type"/>
<xs:complexType name="Garage-Type">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:choice minOccurs="0">
<xs:element name="car" type="Car-Type" minOccurs="0"/>
<xs:element name="boat" type="Boat-Type" minOccurs="0"/>
<xs:element name="bicycle" type="Bike-Type" minOccurs="0"/>
</xs:choice>
</xs:choice>
</xs:sequence>
<xs:attribute name="capacity" type="xs:integer"/>
</xs:complexType>
<xs:complexType name="Car-Type">
<xs:sequence>
<xs:element name="description" type="xs:string" minOccurs="0"/>
<xs:element name="owner" type="Person-Type" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="liter" type="xs:double"/>
<xs:attribute name="cylinder" type="xs:integer"/>
<xs:attribute name="automatic-transmission" type="xs:boolean"/>
<xs:attribute name="name" type="xs:string"/>
</xs:complexType>
<xs:complexType name="Boat-Type">
<xs:sequence>
<xs:element name="description" type="xs:string" minOccurs="0"/>
<xs:element name="owner" type="Person-Type" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="deadweight" type="xs:integer"/>
<xs:attribute name="name" type="xs:string"/>
</xs:complexType>
<xs:complexType name="Bike-Type">
<xs:sequence>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="feature" type="xs:string" minOccurs="0"/>
</xs:choice>
<xs:element name="description" type="xs:string" minOccurs="0"/>
<xs:element name="owner" type="Person-Type" minOccurs="0"/>
</xs:sequence>
<xs:attribute name="name" type="xs:string"/>
</xs:complexType>
<xs:complexType name="Person-Type">
<xs:sequence>
<xs:element name="first-name" type="xs:string" minOccurs="0"/>
<xs:element name="last-name" type="xs:string" minOccurs="0"/>
<xs:element name="birth-date" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
|